<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222"><meta name="generator" content="Hexo 7.3.0">

  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32.ico">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16.ico">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">



<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" integrity="sha256-wiz7ZSCn/btzhjKDQBms9Hx4sSeUYsDrTLg7roPstac=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancyapps-ui/5.0.28/fancybox/fancybox.css" integrity="sha256-6cQIC71/iBIYXFK+0RHAvwmjwWzkWd+r7v/BX3/vZDc=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/pace/1.2.4/themes/green/pace-theme-minimal.css">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/pace/1.2.4/pace.min.js" integrity="sha256-gqd7YTjg/BtfqWSwsJOvndl0Bxc8gFImLEkXQT8+qj0=" crossorigin="anonymous"></script>

<script class="next-config" data-name="main" type="application/json">{"hostname":"sumumm.github.io","root":"/","images":"/images","scheme":"Gemini","darkmode":false,"version":"8.19.2","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":{"enable":true,"style":"mac"},"fold":{"enable":true,"height":300},"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":true,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":true,"transition":{"menu_item":"fadeInDown","post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果：${query}","hits_time":"找到 ${hits} 个搜索结果（用时 ${time} 毫秒）","hits":"找到 ${hits} 个搜索结果"},"path":"/search.xml","localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false}}</script><script src="/js/config.js"></script>

    <meta name="description" content="本文主要是设备树基础知识的相关笔记，若笔记中有错误或者不合适的地方，欢迎批评指正😃。">
<meta property="og:type" content="article">
<meta property="og:title" content="LV10-08-设备树-01-设备树基础知识">
<meta property="og:url" content="https://sumumm.github.io/post/6daf9146.html">
<meta property="og:site_name" content="苏木">
<meta property="og:description" content="本文主要是设备树基础知识的相关笔记，若笔记中有错误或者不合适的地方，欢迎批评指正😃。">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV10-%E9%A9%B1%E5%8A%A8%E5%BC%80%E5%8F%91/LV10-08-%E8%AE%BE%E5%A4%87%E6%A0%91-01-%E8%AE%BE%E5%A4%87%E6%A0%91%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/img/image-20220901181151039.png">
<meta property="og:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV10-%E9%A9%B1%E5%8A%A8%E5%BC%80%E5%8F%91/LV10-08-%E8%AE%BE%E5%A4%87%E6%A0%91-01-%E8%AE%BE%E5%A4%87%E6%A0%91%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/img/image-20220902082931968.png">
<meta property="article:published_time" content="2023-07-08T10:58:30.000Z">
<meta property="article:modified_time" content="2025-06-13T16:25:57.004Z">
<meta property="article:author" content="苏木">
<meta property="article:tag" content="LV10-驱动开发">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV10-%E9%A9%B1%E5%8A%A8%E5%BC%80%E5%8F%91/LV10-08-%E8%AE%BE%E5%A4%87%E6%A0%91-01-%E8%AE%BE%E5%A4%87%E6%A0%91%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/img/image-20220901181151039.png">


<link rel="canonical" href="https://sumumm.github.io/post/6daf9146.html">



<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":false,"isPost":true,"lang":"zh-CN","comments":true,"permalink":"https://sumumm.github.io/post/6daf9146.html","path":"post/6daf9146.html","title":"LV10-08-设备树-01-设备树基础知识"}</script>

<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>LV10-08-设备树-01-设备树基础知识 | 苏木</title>
  








    <script src="/js/browser_tools_disable.js"></script>

  <noscript>
    <link rel="stylesheet" href="/css/noscript.css">
  </noscript>
<!-- hexo injector head_end start --><link rel="stylesheet" href="https://unpkg.com/hexo-next-tags-plus@latest/lib/tag_plus.css" media="defer" onload="this.media='all'"><!-- hexo injector head_end end --></head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <div class="column">
      <header class="header" itemscope itemtype="http://schema.org/WPHeader"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏" role="button">
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <i class="logo-line"></i>
      <p class="site-title">苏木</p>
      <i class="logo-line"></i>
    </a>
      <p class="site-subtitle" itemprop="description">我的学习之路</p>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger" aria-label="搜索" role="button">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>



<nav class="site-nav">
  <ul class="main-menu menu"><li class="menu-item menu-item-home"><a href="/" rel="section"><i class="fa fa-home fa-fw"></i>苏木的家</a></li><li class="menu-item menu-item-categories"><a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类页<span class="badge">42</span></a></li><li class="menu-item menu-item-archives"><a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档页<span class="badge">673</span></a></li><li class="menu-item menu-item-flink"><a href="/flink/" rel="section"><i class="fa fa-link fa-fw"></i>友人帐</a></li><li class="menu-item menu-item-about"><a href="/about/" rel="section"><i class="fa fa-user fa-fw"></i>关于我</a></li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup"><div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off" maxlength="80"
           placeholder="搜索..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close" role="button">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div class="search-result-container no-result">
  <div class="search-result-icon">
    <i class="fa fa-spinner fa-pulse fa-5x"></i>
  </div>
</div>

    </div>
  </div>

</header>
        
  
  <aside class="sidebar">

    <div class="sidebar-inner sidebar-nav-active sidebar-toc-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
            <div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#%E4%B8%80%E3%80%81%E8%AE%BE%E5%A4%87%E6%A0%91%E7%AE%80%E4%BB%8B"><span class="nav-text">一、设备树简介</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#1-%E4%BB%80%E4%B9%88%E6%98%AF%E8%AE%BE%E5%A4%87%E6%A0%91"><span class="nav-text">1. 什么是设备树</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2-dts%E3%80%81dtb%E5%92%8Cdtsi"><span class="nav-text">2. dts、dtb和dtsi</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-%E5%9C%A8%E7%B3%BB%E7%BB%9F%E4%B8%AD%E7%9A%84%E4%BD%93%E7%8E%B0"><span class="nav-text">3. 在系统中的体现</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E4%BA%8C%E3%80%81%E5%9F%BA%E6%9C%AC%E8%AF%AD%E6%B3%95"><span class="nav-text">二、基本语法</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#1-dtsi%E5%A4%B4%E6%96%87%E4%BB%B6"><span class="nav-text">1. dtsi头文件</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2-%E8%AE%BE%E5%A4%87%E8%8A%82%E7%82%B9"><span class="nav-text">2. 设备节点</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#2-1-%E6%A0%B9%E8%8A%82%E7%82%B9"><span class="nav-text">2.1 根节点</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-2-%E7%89%B9%E6%AE%8A%E8%8A%82%E7%82%B9"><span class="nav-text">2.2 特殊节点</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#2-2-1-memory"><span class="nav-text">2.2.1 &#x2F;memory</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#2-2-2-chosen"><span class="nav-text">2.2.2 &#x2F;chosen</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#2-2-3-cpus"><span class="nav-text">2.2.3 &#x2F;cpus</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#2-2-4-aliases"><span class="nav-text">2.2.4 aliases </span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-3-%E8%8A%82%E7%82%B9%E8%AF%AD%E6%B3%95"><span class="nav-text">2.3 节点语法</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-4-%E8%8A%82%E7%82%B9%E5%B1%9E%E6%80%A7%E8%AF%AD%E6%B3%95"><span class="nav-text">2.4 节点属性语法</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B"><span class="nav-text">3. 数据类型</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E4%B8%89%E3%80%81%E6%A0%87%E5%87%86%E5%B1%9E%E6%80%A7"><span class="nav-text">三、标准属性</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#1-compatible"><span class="nav-text">1. compatible </span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2-model"><span class="nav-text">2. model</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-status"><span class="nav-text">3. status</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#4-%E5%AD%90%E8%8A%82%E7%82%B9%E5%9C%B0%E5%9D%80%E4%BF%A1%E6%81%AF"><span class="nav-text">4. 子节点地址信息</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#4-1-address-cells"><span class="nav-text">4.1 #address-cells </span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-2-size-cells"><span class="nav-text">4.2 #size-cells </span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-3-reg"><span class="nav-text">4.3 reg</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-4-%E4%BD%BF%E7%94%A8%E5%AE%9E%E4%BE%8B"><span class="nav-text">4.4 使用实例</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#4-4-1-%E5%AE%9E%E4%BE%8B1"><span class="nav-text">4.4.1 实例1</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#4-4-2-%E5%AE%9E%E4%BE%8B2"><span class="nav-text">4.4.2 实例2</span></a></li></ol></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#5-ranges"><span class="nav-text">5. ranges</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#6-name"><span class="nav-text">6. name</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#7-device-type"><span class="nav-text">7. device_type</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E5%9B%9B%E3%80%81%E5%B8%B8%E7%94%A8%E5%B1%9E%E6%80%A7"><span class="nav-text">四、常用属性</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#1-phandle"><span class="nav-text">1. phandle</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2-reg"><span class="nav-text">2. reg</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-compatible"><span class="nav-text">3. compatible</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#4-%E4%B8%AD%E6%96%AD%E7%9B%B8%E5%85%B3%E5%B1%9E%E6%80%A7"><span class="nav-text">4. 中断相关属性</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#4-1-%E4%B8%AD%E6%96%AD%E6%8E%A7%E5%88%B6%E5%99%A8%E8%8A%82%E7%82%B9"><span class="nav-text">4.1 中断控制器节点</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-2-%E4%B8%AD%E6%96%AD%E6%BA%90%E8%AE%BE%E5%A4%87%E8%8A%82%E7%82%B9"><span class="nav-text">4.2 中断源设备节点</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-3-%E4%BD%BF%E7%94%A8%E5%AE%9E%E4%BE%8B"><span class="nav-text">4.3 使用实例</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#5-gpio%E7%9B%B8%E5%85%B3%E5%B1%9E%E6%80%A7"><span class="nav-text">5. gpio相关属性</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#5-1-GPIO%E6%8E%A7%E5%88%B6%E5%99%A8"><span class="nav-text">5.1 GPIO控制器</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#5-2-GPIO%E4%BD%BF%E7%94%A8%E8%80%85%E8%8A%82%E7%82%B9"><span class="nav-text">5.2 GPIO使用者节点</span></a></li></ol></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E4%BA%94%E3%80%81%E5%B8%B8%E7%94%A8%E6%8E%A5%E5%8F%A3"><span class="nav-text">五、常用接口</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#1-%E4%B8%89%E4%B8%AA%E7%BB%93%E6%9E%84%E4%BD%93"><span class="nav-text">1. 三个结构体</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#1-1-struct-device-node"><span class="nav-text">1.1 struct device_node</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#1-2-struct-property"><span class="nav-text">1.2 struct property </span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#1-3-struct-resource"><span class="nav-text">1.3 struct resource  </span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#2-%E6%9F%A5%E6%89%BE%E8%8A%82%E7%82%B9%E7%9A%84%E5%87%BD%E6%95%B0"><span class="nav-text">2. 查找节点的函数</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#2-1-of-find-node-by-name"><span class="nav-text">2.1 of_find_node_by_name() </span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-2-of-find-node-by-type"><span class="nav-text">2.2 of_find_node_by_type () </span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-3-of-find-compatible-node"><span class="nav-text">2.3 of_find_compatible_node () </span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-4-of-find-matching-node-and-match"><span class="nav-text">2.4 of_find_matching_node_and_match() </span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-5-of-find-node-by-path"><span class="nav-text">2.5 of_find_node_by_path() </span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-%E6%9F%A5%E6%89%BE%E7%88%B6%E5%AD%90%E8%8A%82%E7%82%B9%E7%9A%84%E5%87%BD%E6%95%B0"><span class="nav-text">3. 查找父子节点的函数</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#3-1-of-get-parent"><span class="nav-text">3.1 of_get_parent() </span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-2-of-get-next-child"><span class="nav-text">3.2 of_get_next_child() </span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#4-%E6%8F%90%E5%8F%96%E5%B1%9E%E6%80%A7%E7%9A%84%E5%87%BD%E6%95%B0"><span class="nav-text">4. 提取属性的函数</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#4-1-of-find-property"><span class="nav-text">4.1 of_find_property()</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-2-of-property-count-elems-of-size"><span class="nav-text">4.2 of_property_count_elems_of_size() </span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-3-of-property-read-u32-index"><span class="nav-text">4.3 of_property_read_u32_index() </span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-4-%E8%8E%B7%E5%8F%96%E5%B1%9E%E6%80%A7%E6%95%B0%E7%BB%84%E6%95%B0%E6%8D%AE"><span class="nav-text">4.4 获取属性数组数据</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-5-%E8%8E%B7%E5%8F%96%E5%B1%9E%E6%80%A7%E6%95%B0%E5%80%BC"><span class="nav-text">4.5 获取属性数值</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-6-%E8%8E%B7%E5%8F%96%E5%B1%9E%E6%80%A7%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%80%BC"><span class="nav-text">4.6 获取属性字符串值</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#4-6-1-of-property-read-string"><span class="nav-text">4.6.1 of_property_read_string()</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-7-of-n-addr-cells"><span class="nav-text">4.7 of_n_addr_cells()</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-8-of-n-size-cells"><span class="nav-text">4.8 of_n_size_cells()</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#5-%E5%85%B6%E4%BB%96%E5%B8%B8%E7%94%A8of%E5%87%BD%E6%95%B0"><span class="nav-text">5. 其他常用of函数</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#5-1-of-device-is-compatible"><span class="nav-text">5.1 of_device_is_compatible()</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#5-2-of-get-address"><span class="nav-text">5.2 of_get_address()</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#5-3-of-translate-address"><span class="nav-text">5.3 of_translate_address()</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#5-4-of-property-read-bool"><span class="nav-text">5.4 of_property_read_bool()</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#5-5-of-address-to-resource"><span class="nav-text">5.5 of_address_to_resource()</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#5-6-of-iomap"><span class="nav-text">5.6 of_iomap()</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#5-7-of-get-named-gpio"><span class="nav-text">5.7 of_get_named_gpio()</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#5-8-irq-of-parse-and-map"><span class="nav-text">5.8 irq_of_parse_and_map()</span></a></li></ol></li></ol></li></ol></div>
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="苏木"
      src="/images/avatar.jpg">
  <p class="site-author-name" itemprop="name">苏木</p>
  <div class="site-description" itemprop="description">莫道桑榆晚，为霞尚满天</div>
</div>
<div class="site-state-wrap animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
        <a href="/archives/">
          <span class="site-state-item-count">673</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
          <a href="/categories/">
        <span class="site-state-item-count">42</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
        <span class="site-state-item-count">43</span>
        <span class="site-state-item-name">标签</span>
      </div>
  </nav>
</div>
  <div class="links-of-author animated">
      <span class="links-of-author-item">
        <a href="https://github.com/sumumm" title="GitHub → https:&#x2F;&#x2F;github.com&#x2F;sumumm" rel="noopener me" target="_blank"><i class="fab fa-github fa-fw"></i>GitHub</a>
      </span>
  </div>

        </div>
      </div>
    </div>

    
  </aside>


    </div>

    <div class="main-inner post posts-expand">


  


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://sumumm.github.io/post/6daf9146.html">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.jpg">
      <meta itemprop="name" content="苏木">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="苏木">
      <meta itemprop="description" content="莫道桑榆晚，为霞尚满天">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="LV10-08-设备树-01-设备树基础知识 | 苏木">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          LV10-08-设备树-01-设备树基础知识
        </h1>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2023-07-08 18:58:30" itemprop="dateCreated datePublished" datetime="2023-07-08T18:58:30+08:00">2023-07-08</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/" itemprop="url" rel="index"><span itemprop="name">嵌入式开发</span></a>
        </span>
          ，
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/" itemprop="url" rel="index"><span itemprop="name">01HQ课程体系</span></a>
        </span>
          ，
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV10-%E9%A9%B1%E5%8A%A8%E5%BC%80%E5%8F%91/" itemprop="url" rel="index"><span itemprop="name">LV10-驱动开发</span></a>
        </span>
    </span>

  
    <span class="post-meta-break"></span>
    <span class="post-meta-item" title="本文字数">
      <span class="post-meta-item-icon">
        <i class="far fa-file-word"></i>
      </span>
      <span class="post-meta-item-text">本文字数：</span>
      <span>11k</span>
    </span>
    <span class="post-meta-item" title="阅读时长">
      <span class="post-meta-item-icon">
        <i class="far fa-clock"></i>
      </span>
      <span class="post-meta-item-text">阅读时长 &asymp;</span>
      <span>38 分钟</span>
    </span>
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody"><p>本文主要是设备树基础知识的相关笔记，若笔记中有错误或者不合适的地方，欢迎批评指正😃。</p>
<span id="more"></span>

<!-- Photo: https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV10-%E9%A9%B1%E5%8A%A8%E5%BC%80%E5%8F%91/LV10-08-%E8%AE%BE%E5%A4%87%E6%A0%91-01-%E8%AE%BE%E5%A4%87%E6%A0%91%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/img/ -->

<details class="folding-tag" blue><summary> 点击查看使用工具及版本 </summary>
              <div class='content'>
              <table>    <tr>        <td align="center" width=150px>Windows</td>        <td align="left">windows11</td>    </tr>    <tr>        <td align="center">Ubuntu</td>        <td align="left">Ubuntu16.04的64位版本</td>      </tr>    <tr>        <td align="center">VMware® Workstation 16 Pro</td>        <td align="left">16.2.3 build-19376536</td>      </tr>    <tr>        <td align="center">SecureCRT</td>        <td align="left">Version 8.7.2 (x64 build 2214)   -   正式版-2020年5月14日</td>      </tr>    <tr>        <td align="center" width=150>Linux开发板</td>        <td align="left">华清远见 底板: FS4412_DEV_V5 核心板: FS4412 V2</td>      </tr>    <tr>        <td align="center" width=150>u-boot</td>        <td align="left">2013.01</td>      </tr></table>
              </div>
            </details>

<details class="folding-tag" blue><summary> 点击查看本文参考资料 </summary>
              <div class='content'>
              <table>    <tr><td align="center">参考方向  </td><td align="center">参考原文</td></tr>    <tr><td align="left">---</td><td align="left"><a href="" target="_blank">--- <i class="fa fa-external-link-alt"></i> </a></td></tr></table>
              </div>
            </details>

<details class="folding-tag" blue><summary> 点击查看相关文件下载 </summary>
              <div class='content'>
              <table>    <tr><td align="center">文件</td><td align="center">下载链接</td></tr>    <tr><td align="left">---</td><td align="left"><a href="https://wwz.lanzouy.com/iH1vO09jxavi" target="_blank">--- <i class="fa fa-external-link-alt"></i> </a></td></tr></table>
              </div>
            </details>



<h1 id="一、设备树简介"><a href="#一、设备树简介" class="headerlink" title="一、设备树简介"></a><font size=3>一、设备树简介</font></h1><h2 id="1-什么是设备树"><a href="#1-什么是设备树" class="headerlink" title="1. 什么是设备树"></a><font size=3>1. 什么是设备树</font></h2><p>先来看一张图，自己照着网上画的，比较丑哈，自己凑活看。</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV10-%E9%A9%B1%E5%8A%A8%E5%BC%80%E5%8F%91/LV10-08-%E8%AE%BE%E5%A4%87%E6%A0%91-01-%E8%AE%BE%E5%A4%87%E6%A0%91%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/img/image-20220901181151039.png" alt="image-20220901181151039" style="zoom: 33%;" />

<p>设备树是一种描述硬件信息的数据结构，<code>Linux</code>内核运行时可以通过设备树将硬件信息直接传递给<code>Linux</code>内核，而不再需要在<code>Linux</code>内核中包含大量的冗余编码。</p>
<p>设备树(<code>Device Tree</code>)，将这个词分开就是“设备”和“树”，描述设备树的文件叫做 <code>DTS</code>(<code>DeviceTree Source</code>)，这个<code>DTS</code>文件采用树形结构描述板级设备，也就是开发板上的设备信息，比如<code>CPU</code> 数量、 内存基地址、 <code>IIC</code> 接口上接了哪些设备、 <code>SPI</code> 接口上接了哪些设备等等。</p>
<h2 id="2-dts、dtb和dtsi"><a href="#2-dts、dtb和dtsi" class="headerlink" title="2. dts、dtb和dtsi"></a><font size=3>2. <code>dts</code>、<code>dtb</code>和<code>dtsi</code></font></h2><p>与设备树相关的文件有三种：</p>
<ul>
<li><code>dts</code>：<code>device tree source</code>，设备树源文件。</li>
<li><code>dtsi</code>：<code>device tree source include</code>，类似于头文件，包含一些公共的信息，可被其它设备树文件引用（就是可以被<code>dts</code>文件包含用）。</li>
<li><code>dtb</code> ： <code>device tree binary</code>，是将<code>dts</code>设备树源文件 编译以后得到的二进制文件。</li>
</ul>
<p>我们知道将<code>.c</code> 文件编译为<code>.o</code> 需要用到 <code>gcc</code> 编译器，那么将<code>.dts</code> 编译为<code>.dtb</code>需要什么工具呢？需要用到<code>DTC</code>工具。<code> DTC</code> 工具源码在 <code>Linux</code> 内核的<code>scripts/dtc</code> 目录下 。</p>
<h2 id="3-在系统中的体现"><a href="#3-在系统中的体现" class="headerlink" title="3. 在系统中的体现"></a><font size=3>3. 在系统中的体现</font></h2><p><code>Linux</code> 内核启动的时候会解析设备树中各个节点的信息，并且在根文件系统的<code>/proc/device-tree</code>目录下根据节点名字创建不同目录，例如</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">[root@farsight]#</span><span class="language-bash"><span class="built_in">cd</span> /proc/device-tree/</span></span><br><span class="line"><span class="meta prompt_">[root@farsightdevice-tree]#</span><span class="language-bash"><span class="built_in">ls</span></span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">address-cells                 keypad@100A0000</span></span><br><span class="line"><span class="meta prompt_">#</span><span class="language-bash">size-cells                    lcd0-power-domain@10023C80</span></span><br><span class="line">aliases                        mct@10050000</span><br><span class="line">amba                           memory</span><br><span class="line">cam-power-domain@10023C00      mfc-power-domain@10023C40</span><br><span class="line"><span class="meta prompt_"># </span><span class="language-bash">... ... 后边的省略了</span></span><br></pre></td></tr></table></figure>

<p><code>/proc/device-tree</code>就是根节点<code>/</code>下的所有属性了子节点，我们再进入<code>chosen</code>节点：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">[root@farsightdevice-tree]#</span><span class="language-bash"><span class="built_in">cd</span> chosen/</span></span><br><span class="line"><span class="meta prompt_">[root@farsightchosen]#</span><span class="language-bash"><span class="built_in">ls</span></span></span><br><span class="line">bootargs  name</span><br><span class="line"><span class="meta prompt_">[root@farsightchosen]#</span><span class="language-bash"><span class="built_in">ls</span> -lh</span></span><br><span class="line">total 0</span><br><span class="line">-r--r--r--    1 0        0            116 Jan  1 00:10 bootargs</span><br><span class="line">-r--r--r--    1 0        0              7 Jan  1 00:10 name</span><br><span class="line"><span class="meta prompt_">[root@farsightchosen]#</span><span class="language-bash"><span class="built_in">cat</span> bootargs</span> </span><br><span class="line">root=/dev/nfs nfsroot=192.168.10.101:/home/hk/4nfs/rootfs rw console=ttySAC2,115200 init=/linuxrc ip=192.168.10.102</span><br></pre></td></tr></table></figure>

<p>我们再打开下边这个文件：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">linux<span class="number">-3.14</span>/arch/arm/boot/dts/exynos4412-origen.dts</span><br></pre></td></tr></table></figure>

<p>找到<code>memory</code>节点，信息如下：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">chosen &#123;</span><br><span class="line">    bootargs =<span class="string">&quot;console=ttySAC2,115200&quot;</span>;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<h1 id="二、基本语法"><a href="#二、基本语法" class="headerlink" title="二、基本语法"></a><font size=3>二、基本语法</font></h1><h2 id="1-dtsi头文件"><a href="#1-dtsi头文件" class="headerlink" title="1. dtsi头文件"></a><font size=3>1. <code>dtsi</code>头文件</font></h2><p>和 <code>C</code> 语言一样，设备树也支持头文件，设备树的头文件扩展名为<code>.dtsi</code>，一个<code>  dts</code>文件包含其他<code>dtsi</code>文件的一般格式如下：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&quot;DeviceTree_name.dtsi&quot;</span></span></span><br></pre></td></tr></table></figure>

<p>一般<code>.dtsi</code> 文件用于描述 <code>SOC</code> 的内部外设信息，比如 <code>CPU</code> 架构、主频、外设寄存器地址范围，比如 <code>UART</code>、 <code>IIC</code> 等等。</p>
<p><strong>【注意事项】</strong>在<code>.dts</code> 设备树文件中，可以通过<code>#include</code>来引用<code>.h</code>、<code>.dtsi</code> 和<code>.dts</code> 文件。只是，我们在编写设备树头文件的时候最好选择<code>.dtsi</code>后缀。  </p>
<h2 id="2-设备节点"><a href="#2-设备节点" class="headerlink" title="2. 设备节点"></a><font size=3>2. 设备节点</font></h2><h3 id="2-1-根节点"><a href="#2-1-根节点" class="headerlink" title="2.1 根节点"></a><font size=3>2.1 根节点</font></h3><p>设备树是采用树形结构来描述板子上的设备信息的文件，每个设备都是一个节点，叫做设备节点，每个节点都通过一些属性信息来描述节点信息，属性就是键—值对。例如，  </p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 节选自：linux-3.14/arch/arm/boot/dts/exynos4412-origen.dts */</span></span><br><span class="line">/ &#123;</span><br><span class="line">	model = <span class="string">&quot;Insignal Origen evaluation board based on Exynos4412&quot;</span>;</span><br><span class="line">	compatible = <span class="string">&quot;insignal,origen4412&quot;</span>, <span class="string">&quot;samsung,exynos4412&quot;</span>;</span><br><span class="line"></span><br><span class="line">	memory &#123;</span><br><span class="line">		reg = &lt;<span class="number">0x40000000</span> <span class="number">0x40000000</span>&gt;;</span><br><span class="line">	&#125;;</span><br><span class="line"></span><br><span class="line">	chosen &#123;</span><br><span class="line">		bootargs =<span class="string">&quot;console=ttySAC2,115200&quot;</span>;</span><br><span class="line">	&#125;;</span><br><span class="line"></span><br><span class="line">	firmware@<span class="number">0203F</span>000 &#123;</span><br><span class="line">		compatible = <span class="string">&quot;samsung,secure-firmware&quot;</span>;</span><br><span class="line">		reg = &lt;<span class="number">0x0203F000</span> <span class="number">0x1000</span>&gt;;</span><br><span class="line">	&#125;;</span><br><span class="line">	<span class="comment">/* ... ... */</span></span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<ul>
<li><code>/</code>：是根节点，<strong>每个设备树文件只有一个根节点</strong>。一般来说<code>.dtsi</code>和 <code>.dts</code>文件都会有一个<code>/</code>根节点，因为这两个<code>/</code>根节点的内容会合并成一个根节点。</li>
</ul>
<h3 id="2-2-特殊节点"><a href="#2-2-特殊节点" class="headerlink" title="2.2 特殊节点"></a><font size=3>2.2 特殊节点</font></h3><h4 id="2-2-1-memory"><a href="#2-2-1-memory" class="headerlink" title="2.2.1 /memory"></a><font size=3>2.2.1 <code>/memory</code></font></h4><p>所有设备树文件的必需节点，它定义了系统物理内存的<code>layout</code>，例如，</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">memory &#123;</span><br><span class="line">	reg = &lt;<span class="number">0x40000000</span> <span class="number">0x40000000</span>&gt;; <span class="comment">/* 用来指定内存的地址、大小 */</span></span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<h4 id="2-2-2-chosen"><a href="#2-2-2-chosen" class="headerlink" title="2.2.2 /chosen"></a><font size=3>2.2.2 <code>/chosen</code></font></h4><p>该节点并不是一个真实的设备，主要是用于传递内核启动时使用的参数<code>parameter</code>，例如，</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">chosen &#123;</span><br><span class="line">	bootargs =<span class="string">&quot;console=ttySAC2,115200&quot;</span>;<span class="comment">/* 字符串，内核启动参数, 跟u-boot中设置的bootargs作用一样 */</span> </span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<p>前边我们已将查看过设备树的这个节点在系统中的体现了：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">[root@farsightproc]#</span><span class="language-bash"><span class="built_in">ls</span> -lh /proc/device-tree/chosen/</span></span><br><span class="line">total 0</span><br><span class="line">-r--r--r--    1 0        0            116 Jan  1 00:16 bootargs</span><br><span class="line">-r--r--r--    1 0        0              7 Jan  1 00:16 name</span><br><span class="line"><span class="meta prompt_">[root@farsightproc]#</span><span class="language-bash"><span class="built_in">cat</span> /proc/device-tree/chosen/bootargs</span> </span><br><span class="line">root=/dev/nfs nfsroot=192.168.10.101:/home/hk/4nfs/rootfs rw console=ttySAC2,115200 init=/linuxrc ip=192.168.10.102</span><br></pre></td></tr></table></figure>

<p>但是我们会发现，设备树文件中的参数是很少的，只有<code>&quot;console=ttySAC2,115200&quot;</code>，那么其他的是哪里来的呢？</p>
<p>学习<code>uboot</code> 的时候我们知道， <code>uboot</code> 在启动 <code>Linux </code>内核的时候会将 <code>bootargs</code> 的值传递给 <code>Linux</code>内核， <code>bootargs</code> 会作为 <code>Linux</code> 内核的命令行参数， <code>Linux</code> 内核启动的时候会打印出命令行参数(也就是 <code>uboot</code> 传递进来的 <code>bootargs</code> 的值)。那么这两者有什么关系呢？</p>
<p>我们在<code>uboot</code>的查找<code>chosen  </code>这个字符串，会找到<code>common/fdt_support.c</code>文件中有这么一个函数：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> <span class="title function_">fdt_chosen</span><span class="params">(<span class="type">void</span> *fdt, <span class="type">int</span> force)</span></span><br><span class="line">&#123;</span><br><span class="line">	<span class="comment">// ... ...</span></span><br><span class="line">	<span class="comment">/*</span></span><br><span class="line"><span class="comment">	 * Find the &quot;chosen&quot; node.</span></span><br><span class="line"><span class="comment">	 */</span></span><br><span class="line">	nodeoffset = fdt_path_offset (fdt, <span class="string">&quot;/chosen&quot;</span>);</span><br><span class="line"></span><br><span class="line">	<span class="comment">/*</span></span><br><span class="line"><span class="comment">	 * If there is no &quot;chosen&quot; node in the blob, create it.</span></span><br><span class="line"><span class="comment">	 */</span></span><br><span class="line">	<span class="keyword">if</span> (nodeoffset &lt; <span class="number">0</span>) &#123;</span><br><span class="line">		<span class="comment">/*</span></span><br><span class="line"><span class="comment">		 * Create a new node &quot;/chosen&quot; (offset 0 is root level)</span></span><br><span class="line"><span class="comment">		 */</span></span><br><span class="line">		nodeoffset = fdt_add_subnode(fdt, <span class="number">0</span>, <span class="string">&quot;chosen&quot;</span>);</span><br><span class="line">		<span class="keyword">if</span> (nodeoffset &lt; <span class="number">0</span>) &#123;</span><br><span class="line">			<span class="built_in">printf</span>(<span class="string">&quot;WARNING: could not create /chosen %s.\n&quot;</span>,</span><br><span class="line">				fdt_strerror(nodeoffset));</span><br><span class="line">			<span class="keyword">return</span> nodeoffset;</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line"></span><br><span class="line">	<span class="comment">/*</span></span><br><span class="line"><span class="comment">	 * Create /chosen properites that don&#x27;t exist in the fdt.</span></span><br><span class="line"><span class="comment">	 * If the property exists, update it only if the &quot;force&quot; parameter</span></span><br><span class="line"><span class="comment">	 * is true.</span></span><br><span class="line"><span class="comment">	 */</span></span><br><span class="line">	str = getenv(<span class="string">&quot;bootargs&quot;</span>);</span><br><span class="line">	<span class="keyword">if</span> (str != <span class="literal">NULL</span>) &#123;</span><br><span class="line">		path = fdt_getprop(fdt, nodeoffset, <span class="string">&quot;bootargs&quot;</span>, <span class="literal">NULL</span>);</span><br><span class="line">		<span class="keyword">if</span> ((path == <span class="literal">NULL</span>) || force) &#123;</span><br><span class="line">			err = fdt_setprop(fdt, nodeoffset,</span><br><span class="line">				<span class="string">&quot;bootargs&quot;</span>, str, <span class="built_in">strlen</span>(str)+<span class="number">1</span>);</span><br><span class="line">			<span class="keyword">if</span> (err &lt; <span class="number">0</span>)</span><br><span class="line">				<span class="built_in">printf</span>(<span class="string">&quot;WARNING: could not set bootargs %s.\n&quot;</span>,</span><br><span class="line">					fdt_strerror(err));</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">// ... ...</span></span><br><span class="line">	<span class="keyword">return</span> err;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>所以实际上就是在<code>uboot</code>中的相关函数修改了设备树的这个节点，实际的流程是这样的（引用的正点原子驱动开发手册中的一张图）：</p>
<img data-src="https://fanhua-picture.oss-cn-hangzhou.aliyuncs.com/01%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/01HQ%E8%AF%BE%E7%A8%8B%E4%BD%93%E7%B3%BB/LV10-%E9%A9%B1%E5%8A%A8%E5%BC%80%E5%8F%91/LV10-08-%E8%AE%BE%E5%A4%87%E6%A0%91-01-%E8%AE%BE%E5%A4%87%E6%A0%91%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/img/image-20220902082931968.png" alt="image-20220902082931968" style="zoom: 50%;" />



<h4 id="2-2-3-cpus"><a href="#2-2-3-cpus" class="headerlink" title="2.2.3 /cpus"></a><font size=3>2.2.3 <code>/cpus</code></font></h4><p>多核<code>CPU</code>支持，<code>/cpus</code>节点下有<code>1</code>个或多个<code>cpu</code>子节点,<code>cpu</code>子节点中用<code>reg</code>属性用来标明自己是哪一个<code>cpu</code>，所以 <code>/cpus</code> 中有以下<code>2</code>个属性:</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#address-cells   <span class="comment">/* 在它的子节点的reg属性中, 使用多少个u32整数来描述地址(address) */</span></span></span><br><span class="line"><span class="meta">#size-cells      <span class="comment">/* 在它的子节点的reg属性中, 使用多少个u32整数来描述大小(size) 必须设置为0 */</span></span></span><br></pre></td></tr></table></figure>

<h4 id="2-2-4-aliases"><a href="#2-2-4-aliases" class="headerlink" title="2.2.4 aliases "></a><font size=3>2.2.4 <code>aliases </code></font></h4><p><code>aliases</code> 的意思是“别名”，因此 <code>aliases</code> 节点的主要功能就是定义别名，定义别名的目的就是为了方便访问节点。不过我们一般会在节点命名的时候会加上<code>label</code>，然后通过<code>&amp;label</code>来访问节点，这样也很方便。</p>
<h3 id="2-3-节点语法"><a href="#2-3-节点语法" class="headerlink" title="2.3 节点语法"></a><font size=3>2.3 节点语法</font></h3><p>节点的语法格式如下：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">[label:] node-name[@unit-address] &#123;    </span><br><span class="line">	[properties definitions];    </span><br><span class="line">	[child nodes];</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<ul>
<li><code>label</code>：可选项，节点别名，为了缩短节点访问路径，后续节点中可以使用 <code>&amp;label</code>来表示引用指定节点。</li>
<li><code>node-name</code>：节点的名字。</li>
<li><code>unit-address</code>：设备地址，一般填写该设备寄存器组或内存块的首地址。</li>
<li><code>properties definitions</code>：属性定义。</li>
<li><code>child nodes</code>：子节点。</li>
</ul>
<h3 id="2-4-节点属性语法"><a href="#2-4-节点属性语法" class="headerlink" title="2.4 节点属性语法"></a><font size=3>2.4 节点属性语法</font></h3><p>节点中各个属性的基本语法格式如下：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">[label:] property-name = value;</span><br><span class="line">[label:] property-name;</span><br></pre></td></tr></table></figure>

<p>属性可以无值，对于有值的属性，可以有三种取值：</p>
<ul>
<li><code>arrays of cells</code>，<code>1</code>个或多个<code>32</code>位数据，<code> 64</code>位数据使用<code>2</code>个<code>32</code>位数据表示，数据之间用空格分隔，用尖括号表示(<code>&lt; &gt;</code>)。</li>
<li><code>string</code>，就是字符串， 用双引号表示(<code>&quot; &quot;</code>)。</li>
<li><code>bytestring</code>，<code>1</code>个或多个字节，通过空格分隔,用方括号表示(<code>[]</code>)。</li>
<li>用<code>,</code>分隔的多值。</li>
</ul>
<h2 id="3-数据类型"><a href="#3-数据类型" class="headerlink" title="3. 数据类型"></a><font size=3>3. 数据类型</font></h2><p>在设备树的源码中常用的几种数据类型有以下几种：</p>
<ul>
<li>字符串</li>
</ul>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">compatible = <span class="string">&quot;arm,cortex-a7&quot;</span>; <span class="comment">/* 设置 compatible 属性的值为字符串&quot;arm,cortex-a7&quot; */</span></span><br></pre></td></tr></table></figure>

<ul>
<li><code>32</code>位无符号整数</li>
</ul>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">reg = &lt;<span class="number">0</span>&gt;;               <span class="comment">/* 设置 reg 属性的值为 0 */</span></span><br><span class="line">reg = &lt;<span class="number">0</span> <span class="number">0x123456</span> <span class="number">100</span>&gt;;  <span class="comment">/* reg 的值也可以设置为一组值 */</span></span><br></pre></td></tr></table></figure>

<ul>
<li>字符串列表</li>
</ul>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">compatible = <span class="string">&quot;insignal,origen4412&quot;</span>, <span class="string">&quot;samsung,exynos4412&quot;</span>;</span><br></pre></td></tr></table></figure>

<h1 id="三、标准属性"><a href="#三、标准属性" class="headerlink" title="三、标准属性"></a><font size=3>三、标准属性</font></h1><p>节点是由一堆的属性组成，节点都是具体的设备，不同的设备需要的属性不同，用户可以自定义属性。除了用户自定义属性，有很多属性是标准属性， <code>Linux</code> 下的很多外设驱动都会使用这些标准属性。  </p>
<h2 id="1-compatible"><a href="#1-compatible" class="headerlink" title="1. compatible "></a><font size=3>1. <code>compatible </code></font></h2><p><code>compatible</code> 属性也叫做“兼容性”属性，这是非常重要的一个属性。<code>compatible</code> 属性的值是一个字符串列表， 该属性用于将设备和驱动绑定起来。字符串列表用于选择设备所要使用的驱动程序， <code>compatible</code> 属性的值格式如下所示：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">compatible = <span class="string">&quot;manufacturer,model&quot;</span>;</span><br></pre></td></tr></table></figure>

<ul>
<li><code>manufacturer</code> ：表示厂商。</li>
<li><code> model</code> ：一般是模块对应的驱动名字。</li>
</ul>
<p>一般驱动程序文件都会有一个 <code>OF</code> 匹配表，此 <code>OF</code> 匹配表保存着一些 <code>compatible</code> 值，如果设备节点的 <code>compatible</code> 属性值和 <code>OF</code> 匹配表中的任何一个值相等，那么就表示设备可以使用这个驱动。  </p>
<p>根节点下的<code>compatible</code>属性，用来指定内核中哪个<code>machine_desc</code>可以支持本设备，即描述其兼容哪些平台 。l例如，</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">compatible = <span class="string">&quot;insignal,origen4412&quot;</span>, <span class="string">&quot;samsung,exynos4412&quot;</span>;</span><br></pre></td></tr></table></figure>

<p>通过根节点的 <code>compatible</code>属性可以知道我们所使用的设备，一般第一个值描述了所使用的硬件设备名字，比如这里使用是<code>origen4412</code>这个设备，第二个值描述了设备所使用的<code>SOC</code>，比如这里使用的是<code>exynos4412</code>这颗 <code>SOC</code>。 <code>Linux</code> 内核会通过根节点的 <code>compoatible</code> 属性查看是否支持此设备，如果支持的话设备就会启动<code>Linux</code>内核。  </p>
<h2 id="2-model"><a href="#2-model" class="headerlink" title="2. model"></a><font size=3>2. <code>model</code></font></h2><p><code>model</code> 属性值也是一个字符串，一般 <code>model</code> 属性描述设备模块信息，比如名字 ：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">model = <span class="string">&quot;Insignal Origen evaluation board based on Exynos4412&quot;</span>;</span><br></pre></td></tr></table></figure>

<p>根节点下的<code>model</code>可以用于区分不同的板子，比如有<code>2</code>款板子配置基本一致, 它们的<code>compatible</code>是一样的，那么就通过<code>model</code>来分辨这<code>2</code>款板子。</p>
<h2 id="3-status"><a href="#3-status" class="headerlink" title="3. status"></a><font size=3>3. <code>status</code></font></h2><p><code>status</code> 属性看名字就知道是和设备状态有关的，<code>status</code> 属性值也是字符串，字符串是设备的状态信息，可选的状态如下表：</p>
<table>
    <tr><td align="center">值</td><td align="center">描述</td></tr>
    <tr><td align="left">"okay"</td><td align="left">表明设备是可操作的。</td></tr>
    <tr><td align="left">"disabled" </td><td align="left">表明设备当前是不可操作的，但是在未来可以变为可操作的，比如热插拔设备插入以后。 至于 disabled 的具体含义还要看设备的绑定文档。</td></tr>
    <tr><td align="left">"fail"</td><td align="left">表明设备不可操作，设备检测到了一系列的错误，而且设备也不大可能变得可操作。</td></tr>
    <tr><td align="left">"fail-sss" </td><td align="left">含义和"fail"相同，后面的 sss 部分是检测到的错误内容。</td></tr>
</table>


<h2 id="4-子节点地址信息"><a href="#4-子节点地址信息" class="headerlink" title="4. 子节点地址信息"></a><font size=3>4. 子节点地址信息</font></h2><h3 id="4-1-address-cells"><a href="#4-1-address-cells" class="headerlink" title="4.1 #address-cells "></a><font size=3>4.1 <code>#address-cells</code> </font></h3><p>该属性的值为无符号<code>32</code>位整数，可以用在任何拥有子节点的设备中，用于描述子节点的地址信息。该属性的值决定了子节点 <code>reg</code> 属性中地址信息所占用的字长(<code>32</code> 位)，意思就是在子节点的<code>reg</code>属性中, 使用多少个<code>u32</code>整数来描述地址(<code>address</code>)  。一般使用格式为：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#address-cells = <span class="string">&lt;数字&gt;</span>;</span></span><br></pre></td></tr></table></figure>



<h3 id="4-2-size-cells"><a href="#4-2-size-cells" class="headerlink" title="4.2 #size-cells "></a><font size=3>4.2 <code>#size-cells </code></font></h3><p>该属性的值也为无符号<code>32</code>位整数，可以用在任何拥有子节点的设备中，用于描述子节点的地址信息。该属性的值决定了子节点 <code>reg</code> 属性中长度信息所占的字长(<code>32</code> 位)，意思就是在子节点的<code>reg</code>属性中, 使用多少个<code>u32</code>整数来描述大小(<code>size</code>)  。一般使用格式为：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#size-cells = <span class="string">&lt;数字&gt;</span>;</span></span><br></pre></td></tr></table></figure>



<h3 id="4-3-reg"><a href="#4-3-reg" class="headerlink" title="4.3 reg"></a><font size=3>4.3 <code>reg</code></font></h3><p><code>reg</code>属性是用来描述子结点的地址信息的，一般格式如下：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">reg = &lt;address1 length1 [address2 length2] [address3 length3] [... ...]&gt;;</span><br></pre></td></tr></table></figure>

<p>每个<code>address length</code>组合表示一个地址范围，其中<code>address</code>是起始地址， <code>length</code> 是地址长度， <code>#address-cells</code> 表明 <code>address</code> 这个数据所占用的字长， <code>#size-cells</code> 表明 <code>length</code> 这个数据所占用的字长。</p>
<h3 id="4-4-使用实例"><a href="#4-4-使用实例" class="headerlink" title="4.4 使用实例"></a><font size=3>4.4 使用实例</font></h3><h4 id="4-4-1-实例1"><a href="#4-4-1-实例1" class="headerlink" title="4.4.1 实例1"></a><font size=3>4.4.1 实例1</font></h4><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">spi4 &#123;</span><br><span class="line">	compatible = <span class="string">&quot;spi-gpio&quot;</span>;</span><br><span class="line">	<span class="meta">#address-cells = <span class="string">&lt;1&gt;</span>;</span></span><br><span class="line">	<span class="meta">#size-cells = <span class="string">&lt;0&gt;</span>;</span></span><br><span class="line"></span><br><span class="line">	gpio_spi: gpio_spi@<span class="number">0</span> &#123;</span><br><span class="line">		compatible = <span class="string">&quot;fairchild,74hc595&quot;</span>;</span><br><span class="line">		reg = &lt;<span class="number">0</span>&gt;;</span><br><span class="line">	&#125;;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<ul>
<li><code>#address-cells = &lt;1&gt;;</code></li>
</ul>
<p>这一句表示<code>spi4</code> 的子节点<code>reg</code>属性中起始地址所占用的字长为<code>1 </code>。</p>
<ul>
<li><code>#size-cells = &lt;0&gt;;</code></li>
</ul>
<p>这一句表示<code>spi4</code> 的子节点<code>reg</code>属性中地址长度所占用的字长为 <code>0</code>。</p>
<ul>
<li><code>reg = &lt;0&gt;;</code></li>
</ul>
<p>子节点 <code>gpio_spi: gpio_spi@0</code> 的 <code>reg</code> 属性值为 <code>&lt;0&gt;</code>，因为父节点设置了<code>#addresscells = &lt;1&gt;</code>和<code>#size-cells = &lt;0&gt;</code>，因此 <code>addres=0</code>，没有 <code>length</code> 的值，相当于设置了起始地址，而没有设置地址长度。  </p>
<h4 id="4-4-2-实例2"><a href="#4-4-2-实例2" class="headerlink" title="4.4.2 实例2"></a><font size=3>4.4.2 实例2</font></h4><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">aips3: aips-bus@<span class="number">02200000</span> &#123;</span><br><span class="line">	compatible = <span class="string">&quot;fsl,aips-bus&quot;</span>, <span class="string">&quot;simple-bus&quot;</span>;</span><br><span class="line">	<span class="meta">#address-cells = <span class="string">&lt;1&gt;</span>;</span></span><br><span class="line">	<span class="meta">#size-cells = <span class="string">&lt;1&gt;</span>;</span></span><br><span class="line"></span><br><span class="line">	dcp: dcp@<span class="number">02280000</span> &#123;</span><br><span class="line">		compatible = <span class="string">&quot;fsl,imx6sl-dcp&quot;</span>;</span><br><span class="line">		reg = &lt;<span class="number">0x02280000</span> <span class="number">0x4000</span>&gt;;</span><br><span class="line">	&#125;;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<ul>
<li><code>#address-cells = &lt;1&gt;;</code></li>
</ul>
<p>这一句表示<code>aips3</code> 的子节点<code>reg</code>属性中起始地址所占用的字长为<code>1 </code>。</p>
<ul>
<li><code>#size-cells = &lt;1&gt;;</code></li>
</ul>
<p>这一句表示<code>aips3</code> 的子节点<code>reg</code>属性中地址长度所占用的字长为 <code>1</code>。</p>
<ul>
<li><code>reg = &lt;0x02280000 0x4000&gt;;</code></li>
</ul>
<p>子节点<code>dcp: dcp@02280000</code>的<code>reg</code>属性值为<code>&lt;0x02280000 0x4000&gt;</code>，因为父节点设置了<code>#address-cells = &lt;1&gt;</code>， <code>#size-cells = &lt;1&gt;</code>， <code>address= 0x02280000</code>，<code>length= 0x4000</code>，相当于设置了起始地址为<code>0x02280000</code>，地址长度为<code>0x40000</code>。  </p>
<h2 id="5-ranges"><a href="#5-ranges" class="headerlink" title="5. ranges"></a><font size=3>5. <code>ranges</code></font></h2><p><code>ranges</code>属性值可以为空或者按照(<code>child-bus-address,parent-bus-address</code>，<code>length</code>)格式编写的数字矩阵， <code>ranges</code> 是一个地址映射&#x2F;转换表， <code>ranges</code> 属性每个项目由子地址、父地址和地址空间长度这三部分组成：  </p>
<ul>
<li><code>child-bus-address</code></li>
</ul>
<p>子总线地址空间的物理地址，由父节点的<code>#address-cells </code>确定此物理地址所占用的字长。</p>
<ul>
<li><code>parent-bus-address</code></li>
</ul>
<p>父总线地址空间的物理地址，同样由父节点的<code>#address-cells</code> 确定此物理地址所占用的字长。</p>
<ul>
<li><code>length</code></li>
</ul>
<p>子地址空间的长度，由父节点的<code>#size-cells</code> 确定此地址长度所占用的字长。</p>
<p><strong>【注意事项】</strong>如果<code> ranges</code>属性值为空值，说明子地址空间和父地址空间完全相同，不需要进行地址转换。</p>
<h2 id="6-name"><a href="#6-name" class="headerlink" title="6. name"></a><font size=3>6. <code>name</code></font></h2><p><code>name</code> 属性值为字符串， <code>name</code> 属性用于记录节点名字， <code>name</code> 属性已经被弃用，不推荐使用<code>name</code>属性，一些老的设备树文件可能会使用此属性。  </p>
<h2 id="7-device-type"><a href="#7-device-type" class="headerlink" title="7. device_type"></a><font size=3>7. <code>device_type</code></font></h2><p><code>device_type</code> 属性值为字符串， <code>IEEE 1275</code> 会用到此属性，用于描述设备的 <code>FCode</code>，但是设备树没有 <code>FCode</code>，所以此属性也被抛弃了。此属性只能用于 <code>cpu</code> 节点或者 <code>memory</code> 节点。  </p>
<h1 id="四、常用属性"><a href="#四、常用属性" class="headerlink" title="四、常用属性"></a><font size=3>四、常用属性</font></h1><h2 id="1-phandle"><a href="#1-phandle" class="headerlink" title="1. phandle"></a><font size=3>1. <code>phandle</code></font></h2><p>数字形式的节点标识，在后续节点中属性值性质表示某节点时，可以引用对应节点，例如：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">pic@<span class="number">10000000</span> &#123;    </span><br><span class="line">	phandle = &lt;<span class="number">1</span>&gt;;    </span><br><span class="line">	interrupt-controller;</span><br><span class="line">&#125;;</span><br><span class="line">another-device-node &#123;    </span><br><span class="line">	interrupt-parent = &lt;<span class="number">1</span>&gt;;   <span class="comment">/* 使用phandle值为1来引用上述节点 */</span></span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<h2 id="2-reg"><a href="#2-reg" class="headerlink" title="2. reg"></a><font size=3>2. <code>reg</code></font></h2><p><code>reg</code>属性：表示内存区域<code>region</code>，一般格式如下：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">reg = &lt;address1 length1 [address2 length2] [address3 length3]&gt;;</span><br></pre></td></tr></table></figure>

<p><code>#address-cells</code>：<code>reg</code>属性中, 使用多少个<code>u32</code>整数来描述地址(<code>address</code>)，一般格式如下：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#address-cells = <span class="string">&lt;数字&gt;</span>;</span></span><br></pre></td></tr></table></figure>

<p><code>#size-cells</code>：<code>reg</code>属性中, 使用多少个<code>u32</code>整数来描述大小(<code>size</code>)，一般格式如下：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#size-cells = <span class="string">&lt;数字&gt;</span>;</span></span><br></pre></td></tr></table></figure>

<h2 id="3-compatible"><a href="#3-compatible" class="headerlink" title="3. compatible"></a><font size=3>3. <code>compatible</code></font></h2><p>驱动和设备（设备节点）的匹配依据，<code>compatible</code>（兼容性）的值可以有不止一个字符串以满足不同的需求，一般格式如下：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">compatible = &quot;字符串1&quot;,&quot;字符串2&quot;,...;</span><br></pre></td></tr></table></figure>

<h2 id="4-中断相关属性"><a href="#4-中断相关属性" class="headerlink" title="4. 中断相关属性"></a><font size=3>4. 中断相关属性</font></h2><h3 id="4-1-中断控制器节点"><a href="#4-1-中断控制器节点" class="headerlink" title="4.1 中断控制器节点"></a><font size=3>4.1 中断控制器节点</font></h3><ul>
<li><code>interrupt-controller </code></li>
</ul>
<p>一个无值空属性，用来声明这个<code>node</code>接收中断信号，表示该节点是一个中断控制器。</p>
<ul>
<li><code>#interrupt-cells</code></li>
</ul>
<p>这是中断控制器节点的属性，用来标识这个控制器需要几个单位做中断描述符。用来描述子节点中<code>interrupts</code>属性使用了父节点中的<code>interrupts</code>属性的具体的哪个值。</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">interrupts = &lt;中断域 中断号 触发方式&gt;   <span class="comment">/* 父节点的 #interrupt-cells 属性的值是3 */</span></span><br><span class="line">interrupts = &lt;中断号 触发方式&gt;         <span class="comment">/* 父节点的 #interrupt-cells 属性是2 */</span></span><br></pre></td></tr></table></figure>



<h3 id="4-2-中断源设备节点"><a href="#4-2-中断源设备节点" class="headerlink" title="4.2 中断源设备节点"></a><font size=3>4.2 中断源设备节点</font></h3><ul>
<li><code>interrupt-parent</code></li>
</ul>
<p>标识此设备节点属于哪一个中断控制器，如果没有设置这个属性，会自动依附父节点的，一般格式如下：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">interrupt-parent = &lt;引用某中断控制器节点&gt;</span><br></pre></td></tr></table></figure>

<ul>
<li><code>interrupts</code></li>
</ul>
<p>一个中断标识符列表，表示每一个中断输出信号，一般格式如下：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">interrupts = &lt;中断域 中断号 触发方式&gt;   <span class="comment">/* 父节点的 #interrupt-cells 属性的值是3  */</span></span><br><span class="line">interrupts = &lt;中断号 触发方式&gt;         <span class="comment">/* 父节点的 #interrupt-cells 属性是 2 */</span></span><br></pre></td></tr></table></figure>

<p>这里的中断号指的是组内中断号，触发方式对应数字定义在<code>linux</code>内核源码的这个文件中：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">include/dt-bindings/interrupt-controller/irq.h</span><br></pre></td></tr></table></figure>

<p>宏定义如下所示：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">define</span> IRQ_TYPE_NONE           0</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> IRQ_TYPE_EDGE_RISING    1  <span class="comment">/* low-to-high，上升沿触发 */</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> IRQ_TYPE_EDGE_FALLING   2  <span class="comment">/* high-to-low，下降沿触发 */</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> IRQ_TYPE_EDGE_BOTH      (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING) <span class="comment">/* 3, 上升沿下降沿均触发 */</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> IRQ_TYPE_LEVEL_HIGH     4  <span class="comment">/* high level，高电平触发 */</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> IRQ_TYPE_LEVEL_LOW      8  <span class="comment">/* low level，低电平触发 */</span></span></span><br></pre></td></tr></table></figure>

<h3 id="4-3-使用实例"><a href="#4-3-使用实例" class="headerlink" title="4.3 使用实例"></a><font size=3>4.3 使用实例</font></h3><p>我们可以打开<code>linux</code>内核源码中的这个文件：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">arch/arm/boot/dts/exynos4.dtsi</span><br></pre></td></tr></table></figure>

<p>该文件中对<code>exynos4412</code>的中断控制器(<code>GIC</code>)节点描述如下：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">gic: interrupt-controller@<span class="number">10490000</span> &#123;</span><br><span class="line">	compatible = <span class="string">&quot;arm,cortex-a9-gic&quot;</span>;</span><br><span class="line">	<span class="meta">#interrupt-cells = <span class="string">&lt;3&gt;</span>; <span class="comment">/* 这里意味着，后边使用gic的子节点的interrupt属性需要写中断域 中断号 触发方式*/</span></span></span><br><span class="line">	interrupt-controller;</span><br><span class="line">	reg = &lt;<span class="number">0x10490000</span> <span class="number">0x1000</span>&gt;, &lt;<span class="number">0x10480000</span> <span class="number">0x100</span>&gt;;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<p>我们可以再找一个引用了中断控制器节点的子节点，我们打开这个文件：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">arch/arm/boot/dts/exynos4x12-pinctrl.dtsi</span><br></pre></td></tr></table></figure>

<p>该文件中有什么一个子节点，这里边就包含了一些中断号：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">gpx0: gpx0 &#123;</span><br><span class="line">    gpio-controller;</span><br><span class="line">    <span class="meta">#gpio-cells = <span class="string">&lt;2&gt;</span>;</span></span><br><span class="line"></span><br><span class="line">    interrupt-controller;</span><br><span class="line">    interrupt-parent = &lt;&amp;gic&gt;;</span><br><span class="line">    interrupts = &lt;<span class="number">0</span> <span class="number">16</span> <span class="number">0</span>&gt;, &lt;<span class="number">0</span> <span class="number">17</span> <span class="number">0</span>&gt;, &lt;<span class="number">0</span> <span class="number">18</span> <span class="number">0</span>&gt;, &lt;<span class="number">0</span> <span class="number">19</span> <span class="number">0</span>&gt;,</span><br><span class="line">    &lt;<span class="number">0</span> <span class="number">20</span> <span class="number">0</span>&gt;, &lt;<span class="number">0</span> <span class="number">21</span> <span class="number">0</span>&gt;, &lt;<span class="number">0</span> <span class="number">22</span> <span class="number">0</span>&gt;, &lt;<span class="number">0</span> <span class="number">23</span> <span class="number">0</span>&gt;;</span><br><span class="line">    <span class="meta">#interrupt-cells = <span class="string">&lt;2&gt;</span>; <span class="comment">/* 这里意味着，后边使用GPX引脚作为中断的话，子节点的interrupt属性只需要写中断号和触发方式即可*/</span></span></span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<h2 id="5-gpio相关属性"><a href="#5-gpio相关属性" class="headerlink" title="5. gpio相关属性"></a><font size=3>5. <code>gpio</code>相关属性</font></h2><h3 id="5-1-GPIO控制器"><a href="#5-1-GPIO控制器" class="headerlink" title="5.1 GPIO控制器"></a><font size=3>5.1 <code>GPIO</code>控制器</font></h3><ul>
<li><code>gpio-controller</code></li>
</ul>
<p>无值空属性，用来说明该节点描述的是一个<code>gpio</code>控制器。</p>
<ul>
<li><code>#gpio-cells</code></li>
</ul>
<p>用来表示要用几个<code>cell</code>描述一个<code>GPIO</code>引脚。</p>
<h3 id="5-2-GPIO使用者节点"><a href="#5-2-GPIO使用者节点" class="headerlink" title="5.2 GPIO使用者节点"></a><font size=3>5.2 <code>GPIO</code>使用者节点</font></h3><p>一般语法格式如下：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">xxx-gpio = &lt;&amp;引用GPIO控制器 GPIO标号 工作模式&gt;</span><br></pre></td></tr></table></figure>

<ul>
<li>工作模式：</li>
</ul>
<p><code>1</code>，低电平有效<code>GPIO_ACTIVE_HIGH</code>。</p>
<p><code>0</code>，高电平有效<code>GPIO_ACTIVE_LOW。</code></p>
<h1 id="五、常用接口"><a href="#五、常用接口" class="headerlink" title="五、常用接口"></a><font size=3>五、常用接口</font></h1><p>设备树描述了设备的详细信息，这些信息包括数字类型的、字符串类型的、数组类型的，我们在编写驱动的时候需要获取到这些信息。</p>
<p>比如设备树使用<code>reg</code>属性描述了某个外设的寄存器地址为<code>0X02005482</code>，长度为 <code>0X400</code>，我们在编写驱动的时候需要获取到 <code>reg</code> 属性的<code>0X02005482</code>和<code>0X400</code>这两个值，然后初始化外设。 </p>
<p><code>Linux</code> 内核给我们提供了一系列的函数来获取设备树中的节点或者属性信息，这一系列的函数都有一个统一的前缀<code>of_</code>，所以在很多资料里面也被叫做<code>OF</code>函数。这些<code>OF</code>函数原型都定义在<code>linux</code>内核源码的该文件中：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">include/linux/of.h</span><br></pre></td></tr></table></figure>

<h2 id="1-三个结构体"><a href="#1-三个结构体" class="headerlink" title="1. 三个结构体"></a><font size=3>1. 三个结构体</font></h2><h3 id="1-1-struct-device-node"><a href="#1-1-struct-device-node" class="headerlink" title="1.1 struct device_node"></a><font size=3>1.1 <code>struct device_node</code></font></h3><p>这个结构体定义在<code>include/linux/of.h  </code>文件中，结构体成员如下：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">device_node</span> &#123;</span></span><br><span class="line">        <span class="type">const</span> <span class="type">char</span> *name;       <span class="comment">/* 节点名字 */</span></span><br><span class="line">        <span class="type">const</span> <span class="type">char</span> *type;       <span class="comment">/* 设备类型 */</span></span><br><span class="line">        phandle phandle;</span><br><span class="line">        <span class="type">const</span> <span class="type">char</span> *full_name;  <span class="comment">/* 节点全名 */</span></span><br><span class="line"></span><br><span class="line">        <span class="class"><span class="keyword">struct</span>  <span class="title">property</span> *<span class="title">properties</span>;</span>   <span class="comment">/* 属性 */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span>  <span class="title">property</span> *<span class="title">deadprops</span>;</span>    <span class="comment">/* removed properties, removed 属性 */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span>  <span class="title">device_node</span> *<span class="title">parent</span>;</span>    <span class="comment">/* 父节点 */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span>  <span class="title">device_node</span> *<span class="title">child</span>;</span>     <span class="comment">/* 子节点 */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span>  <span class="title">device_node</span> *<span class="title">sibling</span>;</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span>  <span class="title">device_node</span> *<span class="title">next</span>;</span>      <span class="comment">/* next device of same type */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span>  <span class="title">device_node</span> *<span class="title">allnext</span>;</span>   <span class="comment">/* next in list of all nodes */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span>  <span class="title">proc_dir_entry</span> *<span class="title">pde</span>;</span>    <span class="comment">/* this node&#x27;s proc directory */</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span>  <span class="title">kref</span> <span class="title">kref</span>;</span></span><br><span class="line">        <span class="type">unsigned</span> <span class="type">long</span> _flags;</span><br><span class="line">        <span class="type">void</span>    *data;</span><br><span class="line"><span class="meta">#<span class="keyword">if</span> defined(CONFIG_SPARC)</span></span><br><span class="line">        <span class="type">const</span> <span class="type">char</span> *path_component_name;</span><br><span class="line">        <span class="type">unsigned</span> <span class="type">int</span> unique_id;</span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">of_irq_controller</span> *<span class="title">irq_trans</span>;</span></span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<h3 id="1-2-struct-property"><a href="#1-2-struct-property" class="headerlink" title="1.2 struct property "></a><font size=3>1.2 <code>struct property </code></font></h3><p>节点的属性信息里面保存了驱动所需要的内容， <code>Linux</code> 内核中使用结构体 <code>property</code> 表示属性：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">property</span>&#123;</span></span><br><span class="line">	<span class="type">char</span>    *name;         <span class="comment">/* 属性名字 */</span></span><br><span class="line">	<span class="type">int</span>     length;        <span class="comment">/* 属性长度 */</span> </span><br><span class="line">	<span class="type">void</span>    *value;        <span class="comment">/* 属性值 */</span>   </span><br><span class="line">	<span class="class"><span class="keyword">struct</span> <span class="title">property</span> *<span class="title">next</span>;</span> <span class="comment">/* 下一个属性 */</span></span><br><span class="line">	<span class="type">unsigned</span> <span class="type">long</span> _flags;</span><br><span class="line">	<span class="type">unsigned</span> <span class="type">int</span> unique_id;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<h3 id="1-3-struct-resource"><a href="#1-3-struct-resource" class="headerlink" title="1.3 struct resource  "></a><font size=3>1.3 <code>struct resource  </code></font></h3><p><code>IIC</code>、 <code>SPI</code>、 <code>GPIO</code> 等这些外设都有对应的寄存器，这些寄存器其实就是一组内存空间， <code>Linux</code>内核使用 <code>resource</code> 结构体来描述一段内存空间，<code>resource</code>翻译出来就是资源，因此用<code>resource</code>结构体描述的都是设备资源信息，<code>resource</code>结构体定义在<code>linux</code>内核源码的文件<code>include/linux/ioport.h</code> 中，定义如下 ：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * Resources are tree-like, allowing</span></span><br><span class="line"><span class="comment"> * nesting etc..</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">resource</span> &#123;</span></span><br><span class="line">        <span class="type">resource_size_t</span> start;</span><br><span class="line">        <span class="type">resource_size_t</span> end;</span><br><span class="line">        <span class="type">const</span> <span class="type">char</span> *name;</span><br><span class="line">        <span class="type">unsigned</span> <span class="type">long</span> flags;</span><br><span class="line">        <span class="class"><span class="keyword">struct</span> <span class="title">resource</span> *<span class="title">parent</span>, *<span class="title">sibling</span>, *<span class="title">child</span>;</span></span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<p><strong>【成员说明】</strong></p>
<p>对于 <code>32</code> 位的 <code>SOC </code>来说， <code>resource_size_t</code> 是 <code>u32</code> 类型的。</p>
<ul>
<li><code>start</code> ：表示开始地址。</li>
<li><code>end</code> ：表示结束地址。</li>
<li><code>name</code> ：是这个资源的名字。</li>
<li><code>flags</code>： 是资源标志位，一般表示资源类型，可选的资源标志定义在文件<code>include/linux/ioport.h</code>中。一般来说常见的资源标志就是<code>IORESOURCE_MEM</code>、 <code>IORESOURCE_REG</code>和<code>IORESOURCE_IRQ</code>等。</li>
</ul>
<h2 id="2-查找节点的函数"><a href="#2-查找节点的函数" class="headerlink" title="2. 查找节点的函数"></a><font size=3>2. 查找节点的函数</font></h2><h3 id="2-1-of-find-node-by-name"><a href="#2-1-of-find-node-by-name" class="headerlink" title="2.1 of_find_node_by_name() "></a><font size=3>2.1 <code>of_find_node_by_name() </code></font></h3><p>我们使用以下命令查询一下函数所在头文件：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">grep of_find_node_by_name -r -n ~/5linux/linux-3.14/include</span><br></pre></td></tr></table></figure>

<p>经过查找，我们可以得到如下信息：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 需包含的头文件 */</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;linux/of.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 函数声明 */</span></span><br><span class="line"><span class="keyword">struct</span> device_node *<span class="title function_">of_find_node_by_name</span><span class="params">(<span class="keyword">struct</span> device_node *from, <span class="type">const</span> <span class="type">char</span> *name)</span>;</span><br></pre></td></tr></table></figure>

<p><strong>【函数说明】</strong>该函数通过节点名字查找指定的节点。</p>
<p><strong>【函数参数】</strong></p>
<ul>
<li><code>from</code>：<code>struct device_node *</code>类型，开始查找的节点，如果为<code>NULL</code>表示从根节点开始查找整个设备树。</li>
<li><code>name</code>：<code>char *</code>类型，要查找的节点名字。</li>
</ul>
<p><strong>【返回值】</strong><code>struct device_node *</code>类型，成功返回找到的节点，如果为<code>NULL</code>表示查找失败  。</p>
<p><strong>【使用格式】</strong><code>none</code></p>
<p><strong>【注意事项】</strong><code>none</code></p>
<h3 id="2-2-of-find-node-by-type"><a href="#2-2-of-find-node-by-type" class="headerlink" title="2.2 of_find_node_by_type () "></a><font size=3>2.2 <code>of_find_node_by_type () </code></font></h3><p>我们使用以下命令查询一下函数所在头文件：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">grep of_find_node_by_type -r -n ~/5linux/linux-3.14/include</span><br></pre></td></tr></table></figure>

<p>经过查找，我们可以得到如下信息：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 需包含的头文件 */</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;linux/of.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 函数声明 */</span></span><br><span class="line"><span class="keyword">struct</span> device_node *<span class="title function_">of_find_node_by_type</span><span class="params">(<span class="keyword">struct</span> device_node *from, <span class="type">const</span> <span class="type">char</span> *type)</span>;</span><br></pre></td></tr></table></figure>

<p><strong>【函数说明】</strong>该函数通过<code>device_type</code>属性查找指定的节点 。</p>
<p><strong>【函数参数】</strong></p>
<ul>
<li><code>from</code>：<code>struct device_node *</code>类型，开始查找的节点，如果为<code>NULL</code>表示从根节点开始查找整个设备树。</li>
<li><code>name</code>：<code>char *</code>类型，要查找的节点对应的<code>type</code>字符串，也就是<code>device_type</code>属性值。</li>
</ul>
<p><strong>【返回值】</strong><code>struct device_node *</code>类型，成功返回找到的节点，如果为<code>NULL</code>表示查找失败  。</p>
<p><strong>【使用格式】</strong><code>none</code></p>
<p><strong>【注意事项】</strong><code>none</code></p>
<h3 id="2-3-of-find-compatible-node"><a href="#2-3-of-find-compatible-node" class="headerlink" title="2.3 of_find_compatible_node () "></a><font size=3>2.3 <code>of_find_compatible_node () </code></font></h3><p>我们使用以下命令查询一下函数所在头文件：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">grep of_find_compatible_node -r -n ~/5linux/linux-3.14/include</span><br></pre></td></tr></table></figure>

<p>经过查找，我们可以得到如下信息：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 需包含的头文件 */</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;linux/of.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 函数声明 */</span></span><br><span class="line"><span class="keyword">struct</span> device_node *<span class="title function_">of_find_compatible_node</span><span class="params">(<span class="keyword">struct</span> device_node *from,</span></span><br><span class="line"><span class="params">											<span class="type">const</span> <span class="type">char</span> *type,</span></span><br><span class="line"><span class="params">											<span class="type">const</span> <span class="type">char</span> *compatible)</span>;</span><br></pre></td></tr></table></figure>

<p><strong>【函数说明】</strong>该函数根据<code>device_type</code>和<code>compatible</code>这两个属性查找指定的节点。</p>
<p><strong>【函数参数】</strong></p>
<ul>
<li><code>from</code>：<code>struct device_node *</code>类型，开始查找的节点，如果为<code>NULL</code>表示从根节点开始查找整个设备树 。</li>
<li><code>name</code>：<code>char *</code>类型，要查找的节点对应的<code>type</code>字符串，也就是<code>device_type</code>属性值，可以为 <code>NULL</code>，表示忽略掉 <code>device_type</code> 属性  。</li>
<li><code>compatible</code>：<code>char *</code>类型，要查找的节点所对应的<code>compatible</code>属性列表。</li>
</ul>
<p><strong>【返回值】</strong><code>struct device_node *</code>类型，成功返回找到的节点，如果为<code>NULL</code>表示查找失败  。</p>
<p><strong>【使用格式】</strong><code>none</code></p>
<p><strong>【注意事项】</strong><code>none</code></p>
<h3 id="2-4-of-find-matching-node-and-match"><a href="#2-4-of-find-matching-node-and-match" class="headerlink" title="2.4 of_find_matching_node_and_match() "></a><font size=3>2.4 <code>of_find_matching_node_and_match() </code></font></h3><p>我们使用以下命令查询一下函数所在头文件：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">grep of_find_matching_node_and_match -r -n ~/5linux/linux-3.14/include</span><br></pre></td></tr></table></figure>

<p>经过查找，我们可以得到如下信息：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 需包含的头文件 */</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;linux/of.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 函数声明 */</span></span><br><span class="line"><span class="keyword">struct</span> device_node *<span class="title function_">of_find_matching_node_and_match</span><span class="params">(<span class="keyword">struct</span> device_node *from,</span></span><br><span class="line"><span class="params">													<span class="type">const</span> <span class="keyword">struct</span> of_device_id *matches,</span></span><br><span class="line"><span class="params">													<span class="type">const</span> <span class="keyword">struct</span> of_device_id **match)</span>;</span><br></pre></td></tr></table></figure>

<p><strong>【函数说明】</strong>该函数通过<code>of_device_id</code>匹配表来查找指定的节点。</p>
<p><strong>【函数参数】</strong></p>
<ul>
<li><code>from</code>：<code>struct device_node *</code>类型，开始查找的节点，如果为<code>NULL</code>表示从根节点开始查找整个设备树。</li>
<li><code>matches</code>：<code>struct of_device_id *</code>类型，of_device_id 匹配表，也就是在此匹配表里面查找节点。  </li>
<li><code>match</code>：<code>struct of_device_id *</code>类型，找到的匹配的<code>of_device_id</code>。</li>
</ul>
<p><strong>【返回值】</strong><code>struct device_node *</code>类型，成功返回找到的节点，如果为<code>NULL</code>表示查找失败  。</p>
<p><strong>【使用格式】</strong><code>none</code></p>
<p><strong>【注意事项】</strong><code>none</code></p>
<h3 id="2-5-of-find-node-by-path"><a href="#2-5-of-find-node-by-path" class="headerlink" title="2.5 of_find_node_by_path() "></a><font size=3>2.5 <code>of_find_node_by_path() </code></font></h3><p>我们使用以下命令查询一下函数所在头文件：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">grep of_find_node_by_path -r -n ~/5linux/linux-3.14/include</span><br></pre></td></tr></table></figure>

<p>经过查找，我们可以得到如下信息：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 需包含的头文件 */</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;linux/of.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 函数声明 */</span></span><br><span class="line"><span class="keyword">inline</span> <span class="keyword">struct</span> device_node *<span class="title function_">of_find_node_by_path</span><span class="params">(<span class="type">const</span> <span class="type">char</span> *path)</span>;</span><br></pre></td></tr></table></figure>

<p><strong>【函数说明】</strong>该函数通过路径来查找指定的节点。</p>
<p><strong>【函数参数】</strong></p>
<ul>
<li><code>path</code>：<code>char *</code>类型，带有全路径的节点名，可以使用节点的别名，比如<code>/backlight</code>就是<code>backlight</code>这个节点的全路径。</li>
</ul>
<p><strong>【返回值】</strong><code>struct device_node *</code>类型，成功返回找到的节点，如果为<code>NULL</code>表示查找失败  。</p>
<p><strong>【使用格式】</strong><code>none</code></p>
<p><strong>【注意事项】</strong><code>none</code></p>
<h2 id="3-查找父子节点的函数"><a href="#3-查找父子节点的函数" class="headerlink" title="3. 查找父子节点的函数"></a><font size=3>3. 查找父子节点的函数</font></h2><h3 id="3-1-of-get-parent"><a href="#3-1-of-get-parent" class="headerlink" title="3.1 of_get_parent() "></a><font size=3>3.1 <code>of_get_parent() </code></font></h3><p>我们使用以下命令查询一下函数所在头文件：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">grep of_get_parent -r -n ~/5linux/linux-3.14/include</span><br></pre></td></tr></table></figure>

<p>经过查找，我们可以得到如下信息：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 需包含的头文件 */</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;linux/of.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 函数声明 */</span></span><br><span class="line"><span class="keyword">struct</span> device_node *<span class="title function_">of_get_parent</span><span class="params">(<span class="type">const</span> <span class="keyword">struct</span> device_node *node)</span>;</span><br></pre></td></tr></table></figure>

<p><strong>【函数说明】</strong>该函数获取指定节点的父节点(如果有父节点的话)  。</p>
<p><strong>【函数参数】</strong></p>
<ul>
<li><code>node</code>：<code>struct device_node *</code>类型，要查找的父节点的节点。</li>
</ul>
<p><strong>【返回值】</strong><code>struct device_node *</code>类型，成功返回找到的父节点，如果为<code>NULL</code>表示查找失败  。</p>
<p><strong>【使用格式】</strong><code>none</code></p>
<p><strong>【注意事项】</strong><code>none</code></p>
<h3 id="3-2-of-get-next-child"><a href="#3-2-of-get-next-child" class="headerlink" title="3.2 of_get_next_child() "></a><font size=3>3.2 <code>of_get_next_child() </code></font></h3><p>我们使用以下命令查询一下函数所在头文件：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">grep of_get_next_child -r -n ~/5linux/linux-3.14/include</span><br></pre></td></tr></table></figure>

<p>经过查找，我们可以得到如下信息：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 需包含的头文件 */</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;linux/of.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 函数声明 */</span></span><br><span class="line"><span class="keyword">struct</span> device_node *<span class="title function_">of_get_next_child</span><span class="params">(<span class="type">const</span> <span class="keyword">struct</span> device_node *node,</span></span><br><span class="line"><span class="params">                                      <span class="keyword">struct</span> device_node *prev)</span>;</span><br></pre></td></tr></table></figure>

<p><strong>【函数说明】</strong>该函数用迭代的方式查找子节点。</p>
<p><strong>【函数参数】</strong></p>
<ul>
<li><code>node</code>：<code>struct device_node *</code>类型，父节点。</li>
<li><code>prev</code>：<code>struct device_node *</code>类型，前一个子节点，也就是从哪一个子节点开始迭代地查找下一个子节点。可以设置为<br><code>NULL</code>，表示从第一个子节点开始。</li>
</ul>
<p><strong>【返回值】</strong><code>struct device_node *</code>类型，成功返回找到的下一个子节点，如果为<code>NULL</code>表示查找失败  。</p>
<p><strong>【使用格式】</strong><code>none</code></p>
<p><strong>【注意事项】</strong><code>none</code></p>
<h2 id="4-提取属性的函数"><a href="#4-提取属性的函数" class="headerlink" title="4. 提取属性的函数"></a><font size=3>4. 提取属性的函数</font></h2><h3 id="4-1-of-find-property"><a href="#4-1-of-find-property" class="headerlink" title="4.1 of_find_property()"></a><font size=3>4.1 <code>of_find_property()</code></font></h3><p>我们使用以下命令查询一下函数所在头文件：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">grep of_find_property -r -n ~/5linux/linux-3.14/include</span><br></pre></td></tr></table></figure>

<p>经过查找，我们可以得到如下信息：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 需包含的头文件 */</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;linux/of.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 函数声明 */</span></span><br><span class="line"><span class="keyword">struct</span> property *<span class="title function_">of_find_property</span><span class="params">(<span class="type">const</span> <span class="keyword">struct</span> device_node *np, <span class="type">const</span> <span class="type">char</span> *name, <span class="type">int</span> *lenp)</span>;</span><br></pre></td></tr></table></figure>

<p><strong>【函数说明】</strong>该函数提取指定属性的值 。</p>
<p><strong>【函数参数】</strong></p>
<ul>
<li><code>np</code>：<code>struct device_node *</code>类型，设备节点指针。</li>
<li><code>name</code>：<code>char *</code>类型，属性名字。  </li>
<li><code>lenp</code>：<code>int *</code>类型，属性值的字节数。</li>
</ul>
<p><strong>【返回值】</strong><code>struct property *</code>类型，成功返回属性值的首地址，失败返回<code>NULL</code> 。</p>
<p><strong>【使用格式】</strong><code>none</code></p>
<p><strong>【注意事项】</strong><code>none</code></p>
<h3 id="4-2-of-property-count-elems-of-size"><a href="#4-2-of-property-count-elems-of-size" class="headerlink" title="4.2 of_property_count_elems_of_size() "></a><font size=3>4.2 <code>of_property_count_elems_of_size() </code></font></h3><p>我们使用以下命令查询一下函数所在头文件：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">grep of_property_count_elems_of_size -r -n ~/5linux/linux-3.14/include</span><br></pre></td></tr></table></figure>

<p>经过查找，我们可以得到如下信息：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 需包含的头文件 */</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;linux/of.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 函数声明 */</span></span><br><span class="line"><span class="type">int</span> <span class="title function_">of_property_count_elems_of_size</span><span class="params">(<span class="type">const</span> <span class="keyword">struct</span> device_node *np,</span></span><br><span class="line"><span class="params">                                    <span class="type">const</span> <span class="type">char</span> *propname,</span></span><br><span class="line"><span class="params">                                    <span class="type">int</span> elem_size)</span>;</span><br></pre></td></tr></table></figure>

<p><strong>【函数说明】</strong>该函数用于获取属性中元素的数量，比如<code>reg</code>属性值是一个数组，那么使用此函数可以获取到这个数组的大小。</p>
<p><strong>【函数参数】</strong></p>
<ul>
<li><code>node</code>：<code>struct device_node *</code>类型，设备节点。  </li>
<li><code>propname</code>：<code>char *</code>类型，需要统计元素数量的属性名字。  </li>
<li><code>elem_size</code>：<code>int</code>类型，元素长度。</li>
</ul>
<p><strong>【返回值】</strong><code>int</code>类型，得到的属性元素数量。</p>
<p><strong>【使用格式】</strong><code>none</code></p>
<p><strong>【注意事项】</strong><code>none</code></p>
<h3 id="4-3-of-property-read-u32-index"><a href="#4-3-of-property-read-u32-index" class="headerlink" title="4.3 of_property_read_u32_index() "></a><font size=3>4.3 <code>of_property_read_u32_index() </code></font></h3><p>我们使用以下命令查询一下函数所在头文件：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">grep of_property_read_u32_index -r -n ~/5linux/linux-3.14/include</span><br></pre></td></tr></table></figure>

<p>经过查找，我们可以得到如下信息：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 需包含的头文件 */</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;linux/of.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 函数声明 */</span></span><br><span class="line"><span class="type">int</span> <span class="title function_">of_property_read_u32_index</span><span class="params">(<span class="type">const</span> <span class="keyword">struct</span> device_node *np,</span></span><br><span class="line"><span class="params">                               <span class="type">const</span> <span class="type">char</span> *propname,</span></span><br><span class="line"><span class="params">                               u32 index,</span></span><br><span class="line"><span class="params">                               u32 *out_value)</span>;</span><br></pre></td></tr></table></figure>

<p><strong>【函数说明】</strong>该函数用于从属性中获取指定标号的<code>u32</code>类型数据值(无符号<code>32</code>位)，比如某个属性有多个<code>u32</code>类型的值，那么就可以使用此函数来获取指定标号的数据值。</p>
<p><strong>【函数参数】</strong></p>
<ul>
<li><code>node</code>：<code>struct device_node *</code>类型，设备节点。  </li>
<li><code>propname</code>：<code>char *</code>类型，要读取的属性名字。</li>
<li><code>index</code>：<code>u32</code>类型，要读取的值标号。  </li>
<li><code>out_value</code>：<code>u32</code>类型，读取到的值。</li>
</ul>
<p><strong>【返回值】</strong><code>int</code>类型，得到的属性元素数量。</p>
<p><strong>【使用格式】</strong><code>none</code></p>
<p><strong>【注意事项】</strong><code>none</code></p>
<h3 id="4-4-获取属性数组数据"><a href="#4-4-获取属性数组数据" class="headerlink" title="4.4 获取属性数组数据"></a><font size=3>4.4 获取属性数组数据</font></h3><p>有四个函数分别用于获取<code>u8</code>、 <code>u16</code>、 <code>u32</code> 和 <code>u64</code> 类型的数组数据：  </p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 需包含的头文件 */</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;linux/of.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 函数声明 */</span></span><br><span class="line"><span class="type">int</span> <span class="title function_">of_property_read_u8_array</span><span class="params">(<span class="type">const</span> <span class="keyword">struct</span> device_node *np,</span></span><br><span class="line"><span class="params">                              <span class="type">const</span> <span class="type">char</span> *propname,</span></span><br><span class="line"><span class="params">                              u8 *out_values,</span></span><br><span class="line"><span class="params">                              <span class="type">size_t</span> sz)</span>;</span><br><span class="line"><span class="type">int</span> <span class="title function_">of_property_read_u16_array</span><span class="params">(<span class="type">const</span> <span class="keyword">struct</span> device_node *np,</span></span><br><span class="line"><span class="params">                               <span class="type">const</span> <span class="type">char</span> *propname,</span></span><br><span class="line"><span class="params">                               u16 *out_values,</span></span><br><span class="line"><span class="params">                               <span class="type">size_t</span> sz)</span>;</span><br><span class="line"><span class="type">int</span> <span class="title function_">of_property_read_u32_array</span><span class="params">(<span class="type">const</span> <span class="keyword">struct</span> device_node *np,</span></span><br><span class="line"><span class="params">                               <span class="type">const</span> <span class="type">char</span> *propname,</span></span><br><span class="line"><span class="params">                               u32 *out_values,</span></span><br><span class="line"><span class="params">                               <span class="type">size_t</span> sz)</span>;</span><br><span class="line"><span class="type">int</span> <span class="title function_">of_property_read_u64_array</span><span class="params">(<span class="type">const</span> <span class="keyword">struct</span> device_node *np,</span></span><br><span class="line"><span class="params">                               <span class="type">const</span> <span class="type">char</span> *propname,</span></span><br><span class="line"><span class="params">                               u64 *out_values,</span></span><br><span class="line"><span class="params">                               <span class="type">size_t</span> sz)</span>;</span><br></pre></td></tr></table></figure>

<p><strong>【函数说明】</strong>这 <code>4</code> 个函数分别是读取属性中<code>u8</code>、<code>u16</code>、<code>u32</code>和<code>u64</code>类型的数组数据，比如大多数的<code>reg</code>属性都是数组数据，可以使用这 <code>4</code> 个函数一次读取出<code>reg</code>属性中的所有数据。  </p>
<p><strong>【函数参数】</strong></p>
<ul>
<li><code>np</code>：<code>struct device_node *</code>类型，设备节点。  </li>
<li><code>propname</code>：<code>char *</code>类型，要读取的属性名字。</li>
<li><code>out_values</code>：表示读取到的数组值 ，分别为<code>u8</code>、<code>u16</code>、<code>u32</code> 和 <code>u64</code>。</li>
<li><code>sz</code>：<code>size_t</code>类型，要读取的数组元素数量。</li>
</ul>
<p><strong>【返回值】</strong><code>int</code>类型。读取成功返回<code>0</code>，读取失败返回一个负值。 <code>-EINVAL</code>表示属性不存在， <code>-ENODATA </code>表示没有要读取的数据， <code>-EOVERFLOW</code>表示属性值列表太小。  </p>
<p><strong>【使用格式】</strong><code>none</code></p>
<p><strong>【注意事项】</strong><code>none</code></p>
<h3 id="4-5-获取属性数值"><a href="#4-5-获取属性数值" class="headerlink" title="4.5 获取属性数值"></a><font size=3>4.5 获取属性数值</font></h3><p>有四个函数分别用于获取<code>u8</code>、 <code>u16</code>、 <code>u32</code> 和 <code>u64</code> 类型的数值数据：  </p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 需包含的头文件 */</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;linux/of.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 函数声明 */</span></span><br><span class="line"><span class="type">int</span> <span class="title function_">of_property_read_u8</span><span class="params">(<span class="type">const</span> <span class="keyword">struct</span> device_node *np,</span></span><br><span class="line"><span class="params">                        <span class="type">const</span> <span class="type">char</span> *propname,</span></span><br><span class="line"><span class="params">                        u8 *out_value)</span>;</span><br><span class="line"><span class="type">int</span> <span class="title function_">of_property_read_u16</span><span class="params">(<span class="type">const</span> <span class="keyword">struct</span> device_node *np,</span></span><br><span class="line"><span class="params">                         <span class="type">const</span> <span class="type">char</span> *propname,</span></span><br><span class="line"><span class="params">                         u16 *out_value)</span>;</span><br><span class="line"><span class="type">int</span> <span class="title function_">of_property_read_u32</span><span class="params">(<span class="type">const</span> <span class="keyword">struct</span> device_node *np,</span></span><br><span class="line"><span class="params">                         <span class="type">const</span> <span class="type">char</span> *propname,</span></span><br><span class="line"><span class="params">                         u32 *out_value)</span>;</span><br><span class="line"><span class="type">int</span> <span class="title function_">of_property_read_u64</span><span class="params">(<span class="type">const</span> <span class="keyword">struct</span> device_node *np,</span></span><br><span class="line"><span class="params">                         <span class="type">const</span> <span class="type">char</span> *propname,</span></span><br><span class="line"><span class="params">                         u64 *out_value)</span>;</span><br></pre></td></tr></table></figure>

<p><strong>【函数说明】</strong>这 <code>4</code> 个函数分别是读取属性中<code>u8</code>、<code>u16</code>、<code>u32</code>和<code>u64</code>类型的数值数据。  </p>
<p><strong>【函数参数】</strong></p>
<ul>
<li><code>np</code>：<code>struct device_node *</code>类型，设备节点。  </li>
<li><code>propname</code>：<code>char *</code>类型，要读取的属性名字。</li>
<li><code>out_values</code>：表示读取到的数值 ，分别为<code>u8</code>、<code>u16</code>、<code>u32</code> 和 <code>u64</code>。</li>
</ul>
<p><strong>【返回值】</strong><code>int</code>类型。读取成功返回<code>0</code>，读取失败返回一个负值。  </p>
<p><strong>【使用格式】</strong><code>none</code></p>
<p><strong>【注意事项】</strong><code>none</code></p>
<h3 id="4-6-获取属性字符串值"><a href="#4-6-获取属性字符串值" class="headerlink" title="4.6 获取属性字符串值"></a><font size=3>4.6 获取属性字符串值</font></h3><h4 id="4-6-1-of-property-read-string"><a href="#4-6-1-of-property-read-string" class="headerlink" title="4.6.1 of_property_read_string()"></a><font size=3>4.6.1 <code>of_property_read_string()</code></font></h4><p>我们使用以下命令查询一下函数所在头文件：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">grep of_property_read_string -r -n ~/5linux/linux-3.14/include</span><br></pre></td></tr></table></figure>

<p>经过查找，我们可以得到如下信息：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 需包含的头文件 */</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;linux/of.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 函数声明 */</span></span><br><span class="line"><span class="type">int</span> <span class="title function_">of_property_read_string</span><span class="params">(<span class="keyword">struct</span> device_node *np,</span></span><br><span class="line"><span class="params">                            <span class="type">const</span> <span class="type">char</span> *propname,</span></span><br><span class="line"><span class="params">                            <span class="type">const</span> <span class="type">char</span> **out_string)</span>;</span><br></pre></td></tr></table></figure>

<p><strong>【函数说明】</strong>该函数用于读取属性中字符串值。</p>
<p><strong>【函数参数】</strong></p>
<ul>
<li><code>np</code>：<code>struct device_node *</code>类型，设备节点指针。</li>
<li><code>propname</code>：<code>char *</code>类型，要读取的属性名字。  </li>
<li><code>out_string</code>：<code>char **</code>类型，读取到的字符串值。</li>
</ul>
<p><strong>【返回值】</strong><code>int</code>类型，成功返回<code>0</code>，失败返回负数，负数的绝对值是错误码 。</p>
<p><strong>【使用格式】</strong>这里写一个简单实例，主要是说明第三个参数的定义使用方式：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 设备树节点 */</span></span><br><span class="line">fs4412-hello-dt&#123;</span><br><span class="line">    compatible = <span class="string">&quot;fs4412,hello-dt&quot;</span>;</span><br><span class="line">    my-name = <span class="string">&quot;my-hello-dt&quot;</span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 需要包含的头文件 */</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;linux/of.h&gt;</span></span></span><br><span class="line"><span class="comment">/* 至少应该有的语句 */</span></span><br><span class="line"><span class="type">const</span> <span class="type">char</span> *str = <span class="literal">NULL</span>;</span><br><span class="line"><span class="keyword">if</span>(of_property_read_string(pnode, <span class="string">&quot;my-name&quot;</span>, &amp;str) &lt; <span class="number">0</span>)</span><br><span class="line">    printk(<span class="string">&quot;of_property_read_string failed!\n&quot;</span>);</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">    printk(<span class="string">&quot;name=%s\n&quot;</span>, str);</span><br></pre></td></tr></table></figure>



<p><strong>【注意事项】</strong><code>none</code></p>
<h3 id="4-7-of-n-addr-cells"><a href="#4-7-of-n-addr-cells" class="headerlink" title="4.7 of_n_addr_cells()"></a><font size=3>4.7 <code>of_n_addr_cells()</code></font></h3><p>我们使用以下命令查询一下函数所在头文件：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">grep of_n_addr_cells -r -n ~/5linux/linux-3.14/include</span><br></pre></td></tr></table></figure>

<p>经过查找，我们可以得到如下信息：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 需包含的头文件 */</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;linux/of.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 函数声明 */</span></span><br><span class="line"><span class="type">int</span> <span class="title function_">of_n_addr_cells</span><span class="params">(<span class="keyword">struct</span> device_node *np)</span>;</span><br></pre></td></tr></table></figure>

<p><strong>【函数说明】</strong>该函数用于获取<code>#address-cells</code>属性值。</p>
<p><strong>【函数参数】</strong></p>
<ul>
<li><code>np</code>：<code>struct device_node *</code>类型，设备节点指针。</li>
</ul>
<p><strong>【返回值】</strong><code>int</code>类型，获取到的<code>#address-cells</code>属性值。</p>
<p><strong>【使用格式】</strong><code>none</code></p>
<p><strong>【注意事项】</strong><code>none</code></p>
<h3 id="4-8-of-n-size-cells"><a href="#4-8-of-n-size-cells" class="headerlink" title="4.8 of_n_size_cells()"></a><font size=3>4.8 <code>of_n_size_cells()</code></font></h3><p>我们使用以下命令查询一下函数所在头文件：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">grep of_n_size_cells -r -n ~/5linux/linux-3.14/include</span><br></pre></td></tr></table></figure>

<p>经过查找，我们可以得到如下信息：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 需包含的头文件 */</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;linux/of.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 函数声明 */</span></span><br><span class="line"><span class="type">int</span> <span class="title function_">of_n_size_cells</span><span class="params">(<span class="keyword">struct</span> device_node *np)</span>;</span><br></pre></td></tr></table></figure>

<p><strong>【函数说明】</strong>该函数用于获取<code>#size-cells </code>属性值。</p>
<p><strong>【函数参数】</strong></p>
<ul>
<li><code>np</code>：<code>struct device_node *</code>类型，设备节点指针。</li>
</ul>
<p><strong>【返回值】</strong><code>int</code>类型，获取到的<code>#size-cells   </code>属性值。</p>
<p><strong>【使用格式】</strong><code>none</code></p>
<p><strong>【注意事项】</strong><code>none</code></p>
<h2 id="5-其他常用of函数"><a href="#5-其他常用of函数" class="headerlink" title="5. 其他常用of函数"></a><font size=3>5. 其他常用<code>of</code>函数</font></h2><h3 id="5-1-of-device-is-compatible"><a href="#5-1-of-device-is-compatible" class="headerlink" title="5.1 of_device_is_compatible()"></a><font size=3>5.1 <code>of_device_is_compatible()</code></font></h3><p>我们使用以下命令查询一下函数所在头文件：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">grep of_device_is_compatible -r -n ~/5linux/linux-3.14/include</span><br></pre></td></tr></table></figure>

<p>经过查找，我们可以得到如下信息：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 需包含的头文件 */</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;linux/of.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 函数声明 */</span></span><br><span class="line"><span class="type">int</span> <span class="title function_">of_device_is_compatible</span><span class="params">(<span class="type">const</span> <span class="keyword">struct</span> device_node *device,</span></span><br><span class="line"><span class="params">                            <span class="type">const</span> <span class="type">char</span> *compat)</span>;</span><br></pre></td></tr></table></figure>

<p><strong>【函数说明】</strong>该函数用于查看节点的<code>compatible</code>属性是否有包含<code>compat</code>指定的字符串，也就是检查设备节点的兼容性。</p>
<p><strong>【函数参数】</strong></p>
<ul>
<li><code>device</code>：<code>struct device_node *</code>类型，设备节点指针。</li>
<li><code>compat</code>：<code>char *</code>类型，要查看的字符串。</li>
</ul>
<p><strong>【返回值】</strong><code>int</code>类型，返回<code>0</code>表示节点的<code>compatible</code>属性中不包含 <code>compat</code> 指定的字符串； 返回一个正数表示节点的<code>compatible</code><br>属性中包含 <code>compat</code> 指定的字符串。  </p>
<p><strong>【使用格式】</strong><code>none</code></p>
<p><strong>【注意事项】</strong><code>none</code></p>
<h3 id="5-2-of-get-address"><a href="#5-2-of-get-address" class="headerlink" title="5.2 of_get_address()"></a><font size=3>5.2 <code>of_get_address()</code></font></h3><p>我们使用以下命令查询一下函数所在头文件：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">grep of_get_address -r -n ~/5linux/linux-3.14/include</span><br></pre></td></tr></table></figure>

<p>经过查找，我们可以得到如下信息：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 需包含的头文件 */</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;linux/of.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 函数声明 */</span></span><br><span class="line"><span class="type">const</span> __be32 *<span class="title function_">of_get_address</span><span class="params">(<span class="keyword">struct</span> device_node *dev,</span></span><br><span class="line"><span class="params">                             <span class="type">int</span> index,</span></span><br><span class="line"><span class="params">                             u64 *size,</span></span><br><span class="line"><span class="params">                             <span class="type">unsigned</span> <span class="type">int</span> *flags)</span>;</span><br></pre></td></tr></table></figure>

<p><strong>【函数说明】</strong>该函数用于获取地址相关属性，主要是<code>reg</code>或者<code>assigned-addresses</code>属性值。</p>
<p><strong>【函数参数】</strong></p>
<ul>
<li><code>dev</code>：<code>struct device_node *</code>类型，设备节点指针。</li>
<li><code>index</code>：<code>int</code>类型，要读取的地址标号。  </li>
<li><code>size</code>：<code>u64 *</code>类型，地址长度  。</li>
<li><code>flags</code>：<code>unsigned int *</code>类型，参数，比如<code>IORESOURCE_IO</code>、 <code>IORESOURCE_MEM</code>等。</li>
</ul>
<p><strong>【返回值】</strong><code>__be32 *</code>类型，成功返回读取到的地址数据首地址，读取失败返回<code>NULL</code>。  </p>
<p><strong>【使用格式】</strong><code>none</code></p>
<p><strong>【注意事项】</strong><code>none</code></p>
<h3 id="5-3-of-translate-address"><a href="#5-3-of-translate-address" class="headerlink" title="5.3 of_translate_address()"></a><font size=3>5.3 <code>of_translate_address()</code></font></h3><p>我们使用以下命令查询一下函数所在头文件：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">grep of_translate_address -r -n ~/5linux/linux-3.14/include</span><br></pre></td></tr></table></figure>

<p>经过查找，我们可以得到如下信息：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 需包含的头文件 */</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;linux/of.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 函数声明 */</span></span><br><span class="line">u64 <span class="title function_">of_translate_address</span><span class="params">(<span class="keyword">struct</span> device_node *dev</span></span><br><span class="line"><span class="params">                         <span class="type">const</span> __be32 *in_addr)</span>;</span><br></pre></td></tr></table></figure>

<p><strong>【函数说明】</strong>该函数用于将从设备树读取到的地址转换为物理地址。</p>
<p><strong>【函数参数】</strong></p>
<ul>
<li><code>dev</code>：<code>struct device_node *</code>类型，设备节点指针。</li>
<li><code>in_addr</code>：<code>__be32 *</code>类型，要转换的地址。</li>
</ul>
<p><strong>【返回值】</strong><code>u64</code>类型，得到的物理地址，如果为<code>OF_BAD_ADDR</code>的话表示转换失败。  </p>
<p><strong>【使用格式】</strong><code>none</code></p>
<p><strong>【注意事项】</strong><code>none</code></p>
<h3 id="5-4-of-property-read-bool"><a href="#5-4-of-property-read-bool" class="headerlink" title="5.4 of_property_read_bool()"></a><font size=3>5.4 <code>of_property_read_bool()</code></font></h3><p>我们使用以下命令查询一下函数所在头文件：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">grep of_property_read_bool -r -n ~/5linux/linux-3.14/include</span><br></pre></td></tr></table></figure>

<p>经过查找，我们可以得到如下信息：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 需包含的头文件 */</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;linux/of.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 函数声明 */</span></span><br><span class="line"><span class="type">int</span> <span class="title function_">of_property_read_bool</span><span class="params">(<span class="type">const</span> <span class="keyword">struct</span> device_node *np,</span></span><br><span class="line"><span class="params">                          <span class="type">const</span> <span class="type">char</span> *propname)</span>;</span><br></pre></td></tr></table></figure>

<p><strong>【函数说明】</strong>该函数用于判断指定的属性是否存在。</p>
<p><strong>【函数参数】</strong></p>
<ul>
<li><code>dev</code>：<code>struct device_node *</code>类型，设备节点指针。</li>
<li><code>propname</code>：<code>char *</code>类型，要判断是否存在的的属性名称。</li>
</ul>
<p><strong>【返回值】</strong><code>int</code>类型，若属性存在则返回<code>true</code>，不存在则返回<code>false</code>。  </p>
<p><strong>【使用格式】</strong><code>none</code></p>
<p><strong>【注意事项】</strong><code>none</code></p>
<h3 id="5-5-of-address-to-resource"><a href="#5-5-of-address-to-resource" class="headerlink" title="5.5 of_address_to_resource()"></a><font size=3>5.5 <code>of_address_to_resource()</code></font></h3><p>我们使用以下命令查询一下函数所在头文件：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">grep of_address_to_resource -r -n ~/5linux/linux-3.14/include</span><br></pre></td></tr></table></figure>

<p>经过查找，我们可以得到如下信息：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 需包含的头文件 */</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;linux/of.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 函数声明 */</span></span><br><span class="line"><span class="type">int</span> <span class="title function_">of_address_to_resource</span><span class="params">(<span class="keyword">struct</span> device_node *dev,</span></span><br><span class="line"><span class="params">                           <span class="type">int</span> index,</span></span><br><span class="line"><span class="params">                           <span class="keyword">struct</span> resource *r)</span>;</span><br></pre></td></tr></table></figure>

<p><strong>【函数说明】</strong>前边已经介绍过<code>struct resource</code>结构体了，函数看名字像是从设备树里面提取资源值，但是本质上就是将 <code>reg</code> 属性值，然后将其转换为 <code>resource</code> 结构体类型。</p>
<p><strong>【函数参数】</strong></p>
<ul>
<li><code>dev</code>：<code>struct device_node *</code>类型，设备节点指针。</li>
<li><code>index</code>：<code>int</code>类型，地址资源标号。  </li>
<li><code>r</code>：<code>struct resource *</code>类型（前边有介绍），得到的 <code>resource</code> 类型的资源值。</li>
</ul>
<p><strong>【返回值】</strong><code>int</code>类型，成功返回<code>0</code>，失败返回一个负数。  </p>
<p><strong>【使用格式】</strong><code>none</code></p>
<p><strong>【注意事项】</strong><code>none</code></p>
<h3 id="5-6-of-iomap"><a href="#5-6-of-iomap" class="headerlink" title="5.6 of_iomap()"></a><font size=3>5.6 <code>of_iomap()</code></font></h3><p>我们使用以下命令查询一下函数所在头文件：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">grep of_iomap -r -n ~/5linux/linux-3.14/include</span><br></pre></td></tr></table></figure>

<p>经过查找，我们可以得到如下信息：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 需包含的头文件 */</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;linux/of.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 函数声明 */</span></span><br><span class="line"><span class="type">void</span> __iomem *<span class="title function_">of_iomap</span><span class="params">(<span class="keyword">struct</span> device_node *np,</span></span><br><span class="line"><span class="params">                       <span class="type">int</span> index)</span>;</span><br></pre></td></tr></table></figure>

<p><strong>【函数说明】</strong>该函数用于直接内存映射。不使用设备树的话，会使用<code>ioremap()</code> 函数来完成物理地址到虚拟地址的映射，采用设备树以后就可以直接通过<code>of_iomap</code>函数来获取内存地址所对应的虚拟地址，不需要使用<code>ioremap</code>函数了。当然了，我们也可以使用<code>ioremap()</code> 函数来完成物理地址到虚拟地址的内存映射，只是在采用设备树以后，大部分的驱动都使用<code>of_iomap</code>函数了。 <code>of_iomap </code>函数本质上也是将 <code>reg</code> 属性中地址信息转换为虚拟地址，如果 <code>reg</code> 属性有多段的话，可以通过 <code>index</code> 参数指定要完成内存映射的是哪一段 。</p>
<p><strong>【函数参数】</strong></p>
<ul>
<li><code>np</code>：<code>struct device_node *</code>类型，设备节点指针。</li>
<li><code>index</code>：<code>int</code>类型，<code>reg</code> 属性中要完成内存映射的段，如果 <code>reg</code> 属性只有一段的话 <code>index</code> 就设置为 <code>0</code>。</li>
</ul>
<p><strong>【返回值】</strong><code>void __iomem *</code>类型，成功映射的话返回经过内存映射后的虚拟内存首地址，内存映射失败返回<code>NULL</code>。  </p>
<p><strong>【使用格式】</strong><code>none</code></p>
<p><strong>【注意事项】</strong><code>none</code></p>
<h3 id="5-7-of-get-named-gpio"><a href="#5-7-of-get-named-gpio" class="headerlink" title="5.7 of_get_named_gpio()"></a><font size=3>5.7 <code>of_get_named_gpio()</code></font></h3><p>我们使用以下命令查询一下函数所在头文件：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">grep of_get_named_gpio -r -n ~/5linux/linux-3.14/include</span><br></pre></td></tr></table></figure>

<p>经过查找，我们可以得到如下信息：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 需包含的头文件 */</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;linux/of_gpio.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 函数声明 */</span></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * of_get_named_gpio() - Get a GPIO number to use with GPIO API</span></span><br><span class="line"><span class="comment"> * @np:         device node to get GPIO from</span></span><br><span class="line"><span class="comment"> * @propname:   Name of property containing gpio specifier(s)</span></span><br><span class="line"><span class="comment"> * @index:      index of the GPIO</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * Returns GPIO number to use with Linux generic GPIO API, or one of the errno</span></span><br><span class="line"><span class="comment"> * value on the error condition.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="type">static</span> <span class="keyword">inline</span> <span class="type">int</span> <span class="title function_">of_get_named_gpio</span><span class="params">(<span class="keyword">struct</span> device_node *np,</span></span><br><span class="line"><span class="params">                                   <span class="type">const</span> <span class="type">char</span> *propname, <span class="type">int</span> index)</span></span><br><span class="line">&#123;</span><br><span class="line">        <span class="keyword">return</span> of_get_named_gpio_flags(np, propname, index, <span class="literal">NULL</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>【函数说明】</strong>该函数从设备树中提取<code>gpio</code>口。</p>
<p><strong>【函数参数】</strong></p>
<ul>
<li><code>np</code>：<code>struct device_node *</code>类型，设备节点指针。</li>
<li><code>propname</code>：<code>char *</code>类型，包含要获取 <code>GPIO</code> 信息的属性名。</li>
<li><code>index</code>：<code>int</code>类型， <code>GPIO</code> 索引，因为一个属性里面可能包含多个 <code>GPIO</code>，此参数指定要获取哪个 <code>GPIO</code>的编号，如果只有一个 <code>GPIO</code> 信息的话此参数为<code> 0</code>。</li>
</ul>
<p><strong>【返回值】</strong><code>int</code>类型，返回一个正数表示获取到了<code>GPIO</code>编号，获取失败返回一个负数。  </p>
<p><strong>【使用格式】</strong><code>none</code></p>
<p><strong>【注意事项】</strong><code>none</code></p>
<h3 id="5-8-irq-of-parse-and-map"><a href="#5-8-irq-of-parse-and-map" class="headerlink" title="5.8 irq_of_parse_and_map()"></a><font size=3>5.8 <code>irq_of_parse_and_map()</code></font></h3><p>我们使用以下命令查询一下函数所在头文件：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">grep irq_of_parse_and_map -r -n ~/5linux/linux-3.14/include</span><br></pre></td></tr></table></figure>

<p>经过查找，我们可以得到如下信息：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 需包含的头文件 */</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;linux/of_irq.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 函数声明 */</span></span><br><span class="line"><span class="type">unsigned</span> <span class="type">int</span> <span class="title function_">irq_of_parse_and_map</span><span class="params">(<span class="keyword">struct</span> device_node *node, </span></span><br><span class="line"><span class="params">                                  <span class="type">int</span> index)</span>;</span><br></pre></td></tr></table></figure>

<p><strong>【函数说明】</strong>该函数获得设备树中的中断号并进行映射。</p>
<p><strong>【函数参数】</strong></p>
<ul>
<li><code>node</code>：<code>struct device_node *</code>类型，设备节点指针。</li>
<li><code>index</code>：<code>int</code>类型， <code>GPIO</code> 索引，因为一个属性里面可能包含多个 <code>GPIO</code>，此参数指定要获取哪个 <code>GPIO</code>的编号，如果只有一个 <code>GPIO</code> 信息的话此参数为<code> 0</code>。</li>
</ul>
<p><strong>【返回值】</strong><code>int</code>类型，成功返回中断号，失败返回一个负数，绝对值表示错误码。  </p>
<p><strong>【使用格式】</strong><code>none</code></p>
<p><strong>【注意事项】</strong><code>none</code></p>

    </div>

    
    
    

    <footer class="post-footer">




    <div>
        
            <div style="text-align:center;color: #ccc;font-size:14px;">
            ----------本文结束
            <i class="fas fa-fan fa-spin" style="color: #FF1493; font-size: 1rem"></i>
            感谢您的阅读----------
            </div>
        
    </div>





  
  <div class="my_post_copyright"> 
    <p><span>文章标题:</span><a href="/post/6daf9146.html">LV10-08-设备树-01-设备树基础知识</a></p>
    <p><span>文章作者:</span><a href="/" title="欢迎访问 《苏木》 的学习笔记">苏木</a></p>
    <p><span>发布时间:</span>2023年07月08日 - 18:58</p>
    <p><span>最后更新:</span>2025年06月14日 - 00:25</p>
    <p><span>原始链接:</span><a href="/post/6daf9146.html" title="LV10-08-设备树-01-设备树基础知识">https://sumumm.github.io/post/6daf9146.html</a></p>
    <p><span>许可协议:</span><i class="fab fa-creative-commons"></i> <a rel="license" href= "https://creativecommons.org/licenses/by-nc-nd/4.0/" target="_blank" title="Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)">署名-非商业性使用-禁止演绎 4.0 国际</a> 转载请保留原文链接及作者。</p>  
  </div>
  


          <div class="post-tags">
              <a href="/tags/LV10-%E9%A9%B1%E5%8A%A8%E5%BC%80%E5%8F%91/" rel="tag"><i class="fa fa-tag"></i> LV10-驱动开发</a>
          </div>

        

          <div class="post-nav">
            <div class="post-nav-item">
                <a href="/post/2a3d5ad0.html" rel="prev" title="LV10-09-sysfs-01-sysfs简介">
                  <i class="fa fa-angle-left"></i> LV10-09-sysfs-01-sysfs简介
                </a>
            </div>
            <div class="post-nav-item">
                <a href="/post/abc4e840.html" rel="next" title="LV10-07-中断-01-中断处理基础">
                  LV10-07-中断-01-中断处理基础 <i class="fa fa-angle-right"></i>
                </a>
            </div>
          </div>
    </footer>
  </article>
</div>






</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">

  <div class="copyright">
    &copy; 2017 – 
    <span itemprop="copyrightYear">2025</span>
    <span class="with-love">
      <i class="fa fa-heart"></i>
    </span>
    <span class="author" itemprop="copyrightHolder">苏木</span>
  </div>
<div class="wordcount">
  <span class="post-meta-item">
    <span class="post-meta-item-icon">
      <i class="fa fa-chart-line"></i>
    </span>
      <span>站点总字数：</span>
    <span title="站点总字数">3.7m</span>
  </span>
  <span class="post-meta-item">
    <span class="post-meta-item-icon">
      <i class="fa fa-coffee"></i>
    </span>
      <span>站点阅读时长 &asymp;</span>
    <span title="站点阅读时长">225:26</span>
  </span>
</div>




    <span id="sitetime"></span>
    <script defer language=javascript>
        function siteTime()
        {
            window.setTimeout("siteTime()", 1000);
            var seconds = 1000;
            var minutes = seconds * 60;
            var hours = minutes * 60;
            var days = hours * 24;
            var years = days * 365;
            var today = new Date();
            var todayYear = today.getFullYear();
            var todayMonth = today.getMonth()+1;
            var todayDate = today.getDate();
            var todayHour = today.getHours();
            var todayMinute = today.getMinutes();
            var todaySecond = today.getSeconds();
            /*==================================================
            Date.UTC() -- 返回date对象距世界标准时间(UTC)1970年1月1日午夜之间的毫秒数(时间戳)
            year        - 作为date对象的年份，为4位年份值
            month       - 0-11之间的整数，做为date对象的月份
            day         - 1-31之间的整数，做为date对象的天数
            hours       - 0(午夜24点)-23之间的整数，做为date对象的小时数
            minutes     - 0-59之间的整数，做为date对象的分钟数
            seconds     - 0-59之间的整数，做为date对象的秒数
            microseconds - 0-999之间的整数，做为date对象的毫秒数
            ==================================================*/
            var t1 = Date.UTC(2017, 
                              5, 
                              19, 
                              0, 
                              0, 
                              0); //北京时间
            var t2 = Date.UTC(todayYear,todayMonth,todayDate,todayHour,todayMinute,todaySecond);
            var diff = t2-t1;
            var diffYears = Math.floor(diff/years);
            var diffDays = Math.floor((diff/days)-diffYears*365);
            var diffHours = Math.floor((diff-(diffYears*365+diffDays)*days)/hours);
            var diffMinutes = Math.floor((diff-(diffYears*365+diffDays)*days-diffHours*hours)/minutes);
            var diffSeconds = Math.floor((diff-(diffYears*365+diffDays)*days-diffHours*hours-diffMinutes*minutes)/seconds);
            document.getElementById("sitetime").innerHTML="已在这里 "+diffYears+" 年 "+diffDays+" 天 "+diffHours+" 小时 "+diffMinutes+" 分钟 "+diffSeconds+" 秒";
        }
        siteTime();
    </script>



    </div>
  </footer>

  
  <div class="back-to-top" role="button" aria-label="返回顶部">
    <i class="fa fa-arrow-up fa-lg"></i>
    <span>0%</span>
  </div>
  <div class="reading-progress-bar"></div>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/next-theme-pjax/0.6.0/pjax.min.js" integrity="sha256-vxLn1tSKWD4dqbMRyv940UYw4sXgMtYcK6reefzZrao=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/fancyapps-ui/5.0.28/fancybox/fancybox.umd.js" integrity="sha256-ytMJGN3toR+a84u7g7NuHm91VIR06Q41kMWDr2pq7Zo=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/lozad.js/1.16.0/lozad.min.js" integrity="sha256-mOFREFhqmHeQbXpK2lp4nA3qooVgACfh88fpJftLBbc=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/next-boot.js"></script><script src="/js/pjax.js"></script>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/hexo-generator-searchdb/1.4.1/search.js" integrity="sha256-1kfA5uHPf65M5cphT2dvymhkuyHPQp5A53EGZOnOLmc=" crossorigin="anonymous"></script>
<script src="/js/third-party/search/local-search.js"></script>




  <script src="/js/third-party/fancybox.js"></script>

  <script src="/js/third-party/pace.js"></script>


  




  

  <script class="next-config" data-name="enableMath" type="application/json">true</script><script class="next-config" data-name="mathjax" type="application/json">{"enable":true,"tags":"none","js":{"url":"https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.2/es5/tex-mml-chtml.js","integrity":"sha256-MASABpB4tYktI2Oitl4t+78w/lyA+D7b/s9GEP0JOGI="}}</script>
<script src="/js/third-party/math/mathjax.js"></script>


 
        <div id="click-show-text"
            data-mobile = false
            data-text = 富强,民主,文明,和谐,自由,平等,公正,法制,爱国,敬业,诚信,友善
            data-fontsize = 15px
            data-random= false>
        </div>
       

      
        <script async src=https://cdn.jsdelivr.net/npm/hexo-next-mouse-effect@latest/click/showText.js></script>
      

      
    




    <script async src="/js/fancybox_param.js"></script>





<!-- APlayer本体 -->



</body>
</html>
